summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2017-01-19 11:49:04 +0100
committerJose <jose@zeroc.com>2017-01-19 11:49:04 +0100
commit404a62d1c8455a7d6f9a74b14c56e8e9ee1640ab (patch)
treec6bf8cfa188dbb78b19c3017084d499c913e4cd0
parentRemoved unused Info.plist file for Objective-C controller project (diff)
downloadice-404a62d1c8455a7d6f9a74b14c56e8e9ee1640ab.tar.bz2
ice-404a62d1c8455a7d6f9a74b14c56e8e9ee1640ab.tar.xz
ice-404a62d1c8455a7d6f9a74b14c56e8e9ee1640ab.zip
IcePHP Ice::Value implementation & minor extension cleanup
-rw-r--r--cpp/src/slice2php/Main.cpp274
-rw-r--r--php/config/Make.rules13
-rw-r--r--php/lib/Ice.php54
-rw-r--r--php/lib/Ice_ns.php56
-rw-r--r--php/src/php5/Communicator.cpp24
-rw-r--r--php/src/php5/Operation.cpp30
-rw-r--r--php/src/php5/Proxy.cpp68
-rw-r--r--php/src/php5/Proxy.h6
-rw-r--r--php/src/php5/Types.cpp315
-rw-r--r--php/src/php5/Types.h30
-rw-r--r--php/src/php7/Communicator.cpp29
-rw-r--r--php/src/php7/Operation.cpp28
-rw-r--r--php/src/php7/Proxy.cpp69
-rw-r--r--php/src/php7/Proxy.h6
-rw-r--r--php/src/php7/Types.cpp313
-rw-r--r--php/src/php7/Types.h30
-rw-r--r--php/test/Ice/objects/Client.php21
-rw-r--r--php/test/Ice/proxy/Client.php3
-rw-r--r--php/test/Ice/slicing/objects/Client.php2
-rw-r--r--slice/Ice/Communicator.ice2
-rw-r--r--slice/Ice/Connection.ice6
-rw-r--r--slice/Ice/Endpoint.ice8
-rw-r--r--slice/Ice/ObjectFactory.ice2
-rw-r--r--slice/Ice/Properties.ice1
-rw-r--r--slice/Ice/ValueFactory.ice3
25 files changed, 789 insertions, 604 deletions
diff --git a/cpp/src/slice2php/Main.cpp b/cpp/src/slice2php/Main.cpp
index 2817fdab3d6..385ba28dfbe 100644
--- a/cpp/src/slice2php/Main.cpp
+++ b/cpp/src/slice2php/Main.cpp
@@ -30,11 +30,9 @@
#include <sys/stat.h>
#ifdef _WIN32
-#include <direct.h>
-#endif
-
-#ifndef _WIN32
-#include <unistd.h>
+# include <direct.h>
+#else
+# include <unistd.h>
#endif
using namespace std;
@@ -155,21 +153,22 @@ CodeVisitor::visitClassDecl(const ClassDeclPtr& p)
// Handle forward declarations.
//
string scoped = p->scoped();
- string abs = getAbsolute(p, _ns);
if(_classHistory.count(scoped) == 0)
{
startNamespace(p);
string type = getTypeVar(p);
_out << sp << nl << "global " << type << ';';
- if(!p->isLocal())
+
+ bool isInterface = p->isInterface();
+ if(!p->isLocal() && (isInterface || p->definition()->allOperations().size() > 0))
{
_out << nl << "global " << type << "Prx;";
}
_out << nl << "if(!isset(" << type << "))";
_out << sb;
_out << nl << type << " = IcePHP_declareClass('" << scoped << "');";
- if(!p->isLocal())
+ if(!p->isLocal() && (isInterface || p->definition()->allOperations().size() > 0))
{
_out << nl << type << "Prx = IcePHP_declareProxy('" << scoped << "');";
}
@@ -184,6 +183,16 @@ CodeVisitor::visitClassDecl(const ClassDeclPtr& p)
bool
CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
{
+ //
+ // Do not generate any code for php:internal types, those are provided by
+ // IcePHP C++ extension.
+ //
+ StringList metadata = p->getMetaData();
+ if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end())
+ {
+ return false;
+ }
+
string scoped = p->scoped();
string name = getName(p);
string type = getTypeVar(p);
@@ -201,7 +210,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
startNamespace(p);
_out << sp << nl << "global " << type << ';';
- if(!p->isLocal())
+ if(!p->isLocal() && isAbstract)
{
_out << nl << "global " << prxType << ';';
}
@@ -211,50 +220,49 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
//
if(isInterface)
{
- _out << sp << nl << "if(!interface_exists('" << escapeName(abs) << "'))";
- _out << sb;
- _out << nl << "interface " << name;
- if(bases.empty())
+ if(p->isLocal())
{
- if(!p->isLocal())
+ _out << nl << "interface " << name;
+ if(bases.empty())
{
- _out << " extends " << scopedToName("::Ice::Object", _ns);
+ if(!p->isLocal())
+ {
+ _out << " extends " << scopedToName("::Ice::Object", _ns);
+ }
}
- }
- else
- {
- _out << " extends ";
- for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ else
{
- if(q != bases.begin())
+ _out << " extends ";
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
{
- _out << ", ";
+ if(q != bases.begin())
+ {
+ _out << ", ";
+ }
+ _out << getAbsolute(*q, _ns);
}
- _out << getAbsolute(*q, _ns);
}
- }
- _out << sb;
- for(OperationList::iterator oli = ops.begin(); oli != ops.end(); ++oli)
- {
- _out << nl << "public function " << fixIdent((*oli)->name()) << '(';
- ParamDeclList params = (*oli)->parameters();
- for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q)
+ _out << sb;
+ for(OperationList::iterator oli = ops.begin(); oli != ops.end(); ++oli)
{
- if(q != params.begin())
+ _out << nl << "public function " << fixIdent((*oli)->name()) << '(';
+ ParamDeclList params = (*oli)->parameters();
+ for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q)
{
- _out << ", ";
+ if(q != params.begin())
+ {
+ _out << ", ";
+ }
+ _out << '$' << fixIdent((*q)->name());
}
- _out << '$' << fixIdent((*q)->name());
+ _out << ");";
}
- _out << ");";
- }
- _out << eb;
+ _out << eb;
+ }
}
else
{
- _out << sp << nl << "if(!class_exists('" << escapeName(abs) << "'))";
- _out << sb;
_out << nl;
if(isAbstract)
{
@@ -274,10 +282,14 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
{
if(!p->isLocal())
{
- _out << " extends " << scopedToName("::Ice::ObjectImpl", _ns);
+ _out << " extends " << scopedToName("::Ice::Value", _ns);
}
}
- if(!bases.empty())
+
+ //
+ // Value objects don't implement any interfaces.
+ //
+ if(p->isLocal() && !bases.empty())
{
_out << " implements ";
for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
@@ -352,6 +364,14 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
if(!p->isLocal())
{
//
+ // ice_ice
+ //
+ _out << sp << nl << "public function ice_id()";
+ _out << sb;
+ _out << nl << "return '" << scoped << "';";
+ _out << eb;
+
+ //
// ice_staticId
//
_out << sp << nl << "public static function ice_staticId()";
@@ -423,7 +443,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
// Emit a forward declaration for the class in case a data member refers to this type.
//
_out << sp << nl << type << " = IcePHP_declareClass('" << scoped << "');";
- if(!p->isLocal())
+ if(!p->isLocal() && isAbstract)
{
_out << nl << prxType << " = IcePHP_declareProxy('" << scoped << "');";
}
@@ -434,10 +454,11 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
//
const bool preserved = p->hasMetaData("preserve-slice") || p->inheritsMetaData("preserve-slice");
_out << sp << nl << type << " = IcePHP_defineClass('" << scoped << "', '" << escapeName(abs) << "', "
- << p->compactId() << ", " << (isAbstract ? "true" : "false") << ", " << (preserved ? "true" : "false") << ", ";
- if(!base)
+ << p->compactId() << ", " << (preserved ? "true" : "false") << ", "
+ << (isInterface ? "true" : "false") << ", ";
+ if(!base || (isInterface && !p->isLocal()))
{
- _out << "$Ice__t_Object";
+ _out << "$Ice__t_Value";
}
else
{
@@ -445,27 +466,6 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
}
_out << ", ";
//
- // Interfaces
- //
- if(!bases.empty())
- {
- _out << "array(";
- for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
- {
- if(q != bases.begin())
- {
- _out << ", ";
- }
- _out << getTypeVar(*q);
- }
- _out << ')';
- }
- else
- {
- _out << "null";
- }
- _out << ", ";
- //
// Members
//
// Data members are represented as an array:
@@ -498,9 +498,39 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
}
_out << ");";
- if(!p->isLocal())
+ if(!p->isLocal() && isAbstract)
{
- _out << sp << nl << prxType << " = IcePHP_defineProxy(" << type << ");";
+ _out << sp << nl << prxType << " = IcePHP_defineProxy('" << scoped << "', ";
+ if(!base || base->allOperations().empty())
+ {
+ _out << "$Ice__t_ObjectPrx";
+ }
+ else
+ {
+ _out << getTypeVar(base, "Prx");
+ }
+ _out << ", ";
+ //
+ // Interfaces
+ //
+ if(!bases.empty())
+ {
+ _out << "array(";
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ if(q != bases.begin())
+ {
+ _out << ", ";
+ }
+ _out << getTypeVar(*q, "Prx");
+ }
+ _out << ')';
+ }
+ else
+ {
+ _out << "null";
+ }
+ _out << ");";
//
// Define each operation. The arguments to IcePHP_defineOperation are:
@@ -519,7 +549,7 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
ParamDeclList::iterator t;
int count;
- _out << nl << "IcePHP_defineOperation(" << type << ", '" << (*oli)->name() << "', "
+ _out << nl << "IcePHP_defineOperation(" << prxType << ", '" << (*oli)->name() << "', "
<< getOperationMode((*oli)->mode(), _ns) << ", " << getOperationMode((*oli)->sendMode(), _ns)
<< ", " << static_cast<int>((*oli)->format()) << ", ";
for(t = params.begin(), count = 0; t != params.end(); ++t)
@@ -536,8 +566,11 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
}
_out << "array(";
writeType((*t)->type());
- _out << ", " << ((*t)->optional() ? "true" : "false") << ", "
- << ((*t)->optional() ? (*t)->tag() : 0) << ')';
+ if((*t)->optional())
+ {
+ _out << ", " << (*t)->tag();
+ }
+ _out << ')';
++count;
}
}
@@ -564,8 +597,11 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
}
_out << "array(";
writeType((*t)->type());
- _out << ", " << ((*t)->optional() ? "true" : "false") << ", "
- << ((*t)->optional() ? (*t)->tag() : 0) << ')';
+ if((*t)->optional())
+ {
+ _out << ", " << (*t)->tag();
+ }
+ _out << ')';
++count;
}
}
@@ -588,8 +624,11 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
//
_out << "array(";
writeType(returnType);
- _out << ", " << ((*oli)->returnIsOptional() ? "true" : "false") << ", "
- << ((*oli)->returnIsOptional() ? (*oli)->returnTag() : 0) << ')';
+ if((*oli)->returnIsOptional())
+ {
+ _out << ", " << (*oli)->returnTag();
+ }
+ _out << ')';
}
else
{
@@ -619,8 +658,6 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
}
}
- _out << eb;
-
endNamespace();
if(_classHistory.count(scoped) == 0)
@@ -634,6 +671,16 @@ CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
bool
CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
{
+ //
+ // Do not generate any code for php:internal types, those are provided by
+ // IcePHP C++ extension.
+ //
+ StringList metadata = p->getMetaData();
+ if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end())
+ {
+ return false;
+ }
+
string scoped = p->scoped();
string name = getName(p);
string type = getTypeVar(p);
@@ -642,8 +689,6 @@ CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
startNamespace(p);
_out << sp << nl << "global " << type << ';';
- _out << sp << nl << "if(!class_exists('" << escapeName(abs) << "'))";
- _out << sb;
_out << nl << "class " << name << " extends ";
ExceptionPtr base = p->base();
string baseName;
@@ -774,8 +819,6 @@ CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
}
_out << ");";
- _out << eb;
-
endNamespace();
return false;
@@ -784,6 +827,16 @@ CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
bool
CodeVisitor::visitStructStart(const StructPtr& p)
{
+ //
+ // Do not generate any code for php:internal types, those are provided by
+ // IcePHP C++ extension.
+ //
+ StringList metadata = p->getMetaData();
+ if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end())
+ {
+ return false;
+ }
+
string scoped = p->scoped();
string name = getName(p);
string type = getTypeVar(p);
@@ -804,8 +857,6 @@ CodeVisitor::visitStructStart(const StructPtr& p)
startNamespace(p);
_out << sp << nl << "global " << type << ';';
- _out << sp << nl << "if(!class_exists('" << escapeName(abs) << "'))";
- _out << sb;
_out << nl << "class " << name;
_out << sb;
@@ -863,9 +914,6 @@ CodeVisitor::visitStructStart(const StructPtr& p)
_out.dec();
}
_out << "));";
-
- _out << eb;
-
endNamespace();
return false;
@@ -874,6 +922,16 @@ CodeVisitor::visitStructStart(const StructPtr& p)
void
CodeVisitor::visitSequence(const SequencePtr& p)
{
+ //
+ // Do not generate any code for php:internal types, those are provided by
+ // IcePHP C++ extension.
+ //
+ StringList metadata = p->getMetaData();
+ if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end())
+ {
+ return;
+ }
+
string type = getTypeVar(p);
TypePtr content = p->type();
@@ -897,6 +955,16 @@ CodeVisitor::visitSequence(const SequencePtr& p)
void
CodeVisitor::visitDictionary(const DictionaryPtr& p)
{
+ //
+ // Do not generate any code for php:internal types, those are provided by
+ // IcePHP C++ extension.
+ //
+ StringList metadata = p->getMetaData();
+ if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end())
+ {
+ return;
+ }
+
TypePtr keyType = p->keyType();
BuiltinPtr b = BuiltinPtr::dynamicCast(keyType);
if(b)
@@ -955,6 +1023,16 @@ CodeVisitor::visitDictionary(const DictionaryPtr& p)
void
CodeVisitor::visitEnum(const EnumPtr& p)
{
+ //
+ // Do not generate any code for php:internal types, those are provided by
+ // IcePHP C++ extension.
+ //
+ StringList metadata = p->getMetaData();
+ if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end())
+ {
+ return;
+ }
+
string scoped = p->scoped();
string name = getName(p);
string type = getTypeVar(p);
@@ -964,8 +1042,6 @@ CodeVisitor::visitEnum(const EnumPtr& p)
startNamespace(p);
_out << sp << nl << "global " << type << ';';
- _out << sp << nl << "if(!class_exists('" << escapeName(abs) << "'))";
- _out << sb;
_out << nl << "class " << name;
_out << sb;
@@ -993,14 +1069,22 @@ CodeVisitor::visitEnum(const EnumPtr& p)
}
_out << "));";
- _out << eb;
-
endNamespace();
}
void
CodeVisitor::visitConst(const ConstPtr& p)
{
+ //
+ // Do not generate any code for php:internal types, those are provided by
+ // IcePHP C++ extension.
+ //
+ StringList metadata = p->getMetaData();
+ if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end())
+ {
+ return;
+ }
+
string name = getName(p);
string type = getTypeVar(p);
string abs = getAbsolute(p, _ns);
@@ -1118,7 +1202,7 @@ CodeVisitor::writeType(const TypePtr& p)
case Builtin::KindObject:
case Builtin::KindValue:
{
- _out << "$Ice__t_Object";
+ _out << "$Ice__t_Value";
break;
}
case Builtin::KindObjectProxy:
@@ -1138,7 +1222,15 @@ CodeVisitor::writeType(const TypePtr& p)
ProxyPtr prx = ProxyPtr::dynamicCast(p);
if(prx)
{
- _out << getTypeVar(prx->_class(), "Prx");
+ ClassDefPtr def = prx->_class()->definition();
+ if(def->isInterface() || def->allOperations().size() > 0)
+ {
+ _out << getTypeVar(prx->_class(), "Prx");
+ }
+ else
+ {
+ _out << "$Ice__t_ObjectPrx";
+ }
return;
}
diff --git a/php/config/Make.rules b/php/config/Make.rules
index a75af2250d8..db83feb2911 100644
--- a/php/config/Make.rules
+++ b/php/config/Make.rules
@@ -18,6 +18,11 @@ PHP_CONFIG ?= php-config
php_cppflags = $(shell $(PHP_CONFIG) --includes)
+ifeq ($(USE_NAMESPACES),yes)
+php_cppflags := $(php_cppflags) -DICEPHP_USE_NAMESPACES
+slice2php_flags = --namespace
+endif
+
ifeq ($(os),Darwin)
php_ldflags := ${wl}-flat_namespace ${wl}-undefined ${wl}suppress
endif
@@ -81,9 +86,9 @@ endif
$2/$3/%.php: $1/$3/%.ice $2/$3/.depend/%.ice.d $(slice2php_path)
$(E) "Compiling $$<"
- $(Q)$(slice2php_path) -I$1 --output-dir $2/$3 $4 --depend $$< | \
+ $(Q)$(slice2php_path) $(slice2php_flags) -I$1 --output-dir $2/$3 $4 --depend $$< | \
sed 's/\(.*: \\\)/$(subst /,\/,$2)\/$3\/\1/' > $2/$3/.depend/$$(*F).ice.d
- $(Q)$(slice2php_path) -I$1 --output-dir $2/$3 $4 $$<
+ $(Q)$(slice2php_path) $(slice2php_flags) -I$1 --output-dir $2/$3 $4 $$<
distclean clean::
$(E) "Cleaning package $3"
@@ -117,9 +122,9 @@ endif
$1/%.php: $1/%.ice $1/.depend/%.ice.d $(slice2php_path)
$(E) "Compiling $$<"
- $(Q)$(slice2php_path) -I$(slicedir) -I$1 --output-dir $1 $$($1_sliceflags) --depend $$< | \
+ $(Q)$(slice2php_path) $(slice2php_flags) -I$(slicedir) -I$1 --output-dir $1 $$($1_sliceflags) --depend $$< | \
sed 's/\(.*: \\\)/$(subst /,\/,$2)\/$3\/\1/' > $1/.depend/$$(*F).ice.d
- $(Q)$(slice2php_path) -I$(slicedir) -I$1 --output-dir $1 $$($1_sliceflags) $$<
+ $(Q)$(slice2php_path) $(slice2php_flags) -I$(slicedir) -I$1 --output-dir $1 $$($1_sliceflags) $$<
distclean clean::
$(E) "Cleaning $1"
diff --git a/php/lib/Ice.php b/php/lib/Ice.php
index 6187effea00..bc4ecc76f3a 100644
--- a/php/lib/Ice.php
+++ b/php/lib/Ice.php
@@ -56,39 +56,29 @@ abstract class Ice_LocalException extends Ice_Exception
}
}
-interface Ice_Object
+class Ice_Value
{
- public function ice_isA($id);
- public function ice_ping();
- public function ice_ids();
- public function ice_id();
-
- //
- // No need to define these here; the marshaling code will invoke them if defined by a subclass.
- //
- //public function ice_preMarshal();
- //public function ice_postUnmarshal();
-}
-
-abstract class Ice_ObjectImpl implements Ice_Object
-{
- public function ice_isA($id)
+ public function ice_ids()
{
- return array_search($id, ice_ids());
+ return array(ice_id());
}
- public function ice_ping()
+ public function ice_id()
{
+ return "::Ice::Object";
}
+}
- public function ice_ids()
+class Ice_InterfaceByValue extends Ice_Value
+{
+ public function __construct($id)
{
- return array(ice_id());
+ $this->id =$id;
}
-
+
public function ice_id()
{
- return "::Ice::Object";
+ return $this->id;
}
}
@@ -110,13 +100,13 @@ class Ice_ObjectPrxHelper
}
}
-$Ice__t_Object = IcePHP_defineClass('::Ice::Object', "Ice_Object", -1, true, false, null, null, null);
-$Ice__t_ObjectSeq = IcePHP_defineSequence('::Ice::ObjectSeq', $Ice__t_Object);
-$Ice__t_LocalObject = IcePHP_defineClass('::Ice::LocalObject', "Ice_LocalObject", -1, true, false, null, null, null);
-$Ice__t_ObjectPrx = IcePHP_defineProxy($Ice__t_Object);
+$Ice__t_Value = IcePHP_defineClass('::Ice::Object', "Ice_Value", -1, false, false, null, null);
+$Ice__t_ObjectSeq = IcePHP_defineSequence('::Ice::ObjectSeq', $Ice__t_Value);
+$Ice__t_LocalObject = IcePHP_defineClass('::Ice::LocalObject', "Ice_LocalObject", -1, false, false, null, null);
+$Ice__t_ObjectPrx = IcePHP_defineProxy('::Ice::Object', null, null);
$Ice__t_ObjectProxySeq = IcePHP_defineSequence('::Ice::ObjectProxySeq', $Ice__t_ObjectPrx);
-class Ice_UnknownSlicedObject extends Ice_ObjectImpl
+class Ice_UnknownSlicedValue extends Ice_Value
{
public function __construct()
{
@@ -125,7 +115,7 @@ class Ice_UnknownSlicedObject extends Ice_ObjectImpl
public $unknownTypeId;
}
-$Ice__t_UnknownSlicedObject = IcePHP_defineClass('::Ice::UnknownSlicedObject', 'Ice_UnknownSlicedObject', -1, false, true, $Ice__t_Object, null, null);
+$Ice__t_UnknownSlicedValue = IcePHP_defineClass('::Ice::UnknownSlicedValue', 'Ice_UnknownSlicedValue', -1, true, false, $Ice__t_Value, null);
interface Ice_ObjectFactory
{
@@ -193,10 +183,10 @@ $Ice_Protocol_1_0 = new Ice_ProtocolVersion(1, 0);
$Ice_Encoding_1_0 = new Ice_EncodingVersion(1, 0);
$Ice_Encoding_1_1 = new Ice_EncodingVersion(1, 1);
-IcePHP_defineOperation($Ice__t_Object, 'ice_isA', 2, 1, 0, array(array($IcePHP__t_string, false, 0)), null, array($IcePHP__t_bool, false, 0), null);
-IcePHP_defineOperation($Ice__t_Object, 'ice_ping', 2, 1, 0, null, null, null, null);
-IcePHP_defineOperation($Ice__t_Object, 'ice_id', 2, 1, 0, null, null, array($IcePHP__t_string, false, 0), null);
-IcePHP_defineOperation($Ice__t_Object, 'ice_ids', 2, 1, 0, null, null, array($Ice__t_StringSeq, false, 0), null);
+IcePHP_defineOperation($Ice__t_ObjectPrx, 'ice_isA', 2, 1, 0, array(array($IcePHP__t_string)), null, array($IcePHP__t_bool), null);
+IcePHP_defineOperation($Ice__t_ObjectPrx, 'ice_ping', 2, 1, 0, null, null, null, null);
+IcePHP_defineOperation($Ice__t_ObjectPrx, 'ice_id', 2, 1, 0, null, null, array($IcePHP__t_string), null);
+IcePHP_defineOperation($Ice__t_ObjectPrx, 'ice_ids', 2, 1, 0, null, null, array($Ice__t_StringSeq), null);
//
// Proxy comparison functions.
diff --git a/php/lib/Ice_ns.php b/php/lib/Ice_ns.php
index 67893d7ff81..6be529e7857 100644
--- a/php/lib/Ice_ns.php
+++ b/php/lib/Ice_ns.php
@@ -61,39 +61,29 @@ namespace Ice
}
}
- interface Object
+ class Value
{
- public function ice_isA($id);
- public function ice_ping();
- public function ice_ids();
- public function ice_id();
-
- //
- // No need to define these here; the marshaling code will invoke them if defined by a subclass.
- //
- //public function ice_preMarshal();
- //public function ice_postUnmarshal();
- }
-
- abstract class ObjectImpl implements Object
- {
- public function ice_isA($id)
+ public function ice_ids()
{
- return array_search($id, ice_ids());
+ return array(ice_id());
}
- public function ice_ping()
+ public function ice_id()
{
+ return "::Ice::Object";
}
+ }
- public function ice_ids()
+ class InterfaceByValue extends Value
+ {
+ public function __construct($id)
{
- return array(ice_id());
+ $this->id =$id;
}
-
+
public function ice_id()
{
- return "::Ice::Object";
+ return $this->id;
}
}
@@ -115,13 +105,13 @@ namespace Ice
}
}
- $Ice__t_Object = IcePHP_defineClass('::Ice::Object', "\\Ice\\Object", -1, true, false, null, null, null);
- $Ice__t_ObjectSeq = IcePHP_defineSequence('::Ice::ObjectSeq', $Ice__t_Object);
- $Ice__t_LocalObject = IcePHP_defineClass('::Ice::LocalObject', "\\Ice\\LocalObject", -1, true, false, null, null, null);
- $Ice__t_ObjectPrx = IcePHP_defineProxy($Ice__t_Object);
+ $Ice__t_Value = IcePHP_defineClass('::Ice::Object', "\\Ice\\Value", -1, false, false, null, null);
+ $Ice__t_ObjectSeq = IcePHP_defineSequence('::Ice::ObjectSeq', $Ice__t_Value);
+ $Ice__t_LocalObject = IcePHP_defineClass('::Ice::LocalObject', "\\Ice\\LocalObject", -1, false, false, null, null);
+ $Ice__t_ObjectPrx = IcePHP_defineProxy('::Ice::Object', null, null);
$Ice__t_ObjectProxySeq = IcePHP_defineSequence('::Ice::ObjectProxySeq', $Ice__t_ObjectPrx);
- class UnknownSlicedObject extends ObjectImpl
+ class UnknownSlicedValue extends Value
{
public function __construct()
{
@@ -130,7 +120,7 @@ namespace Ice
public $unknownTypeId;
}
- $Ice__t_UnknownSlicedObject = IcePHP_defineClass('::Ice::UnknownSlicedObject', "\\Ice\\UnknownSlicedObject", -1, false, true, $Ice__t_Object, null, null);
+ $Ice__t_UnknownSlicedValue = IcePHP_defineClass('::Ice::UnknownSlicedValue', "\\Ice\\UnknownSlicedValue", -1, true, false, $Ice__t_Value, null);
interface ObjectFactory
{
@@ -138,7 +128,7 @@ namespace Ice
public function destroy();
}
- interface VaueFactory
+ interface ValueFactory
{
public function create($id);
}
@@ -201,10 +191,10 @@ $Ice_Protocol_1_0 = new Ice\ProtocolVersion(1, 0);
$Ice_Encoding_1_0 = new Ice\EncodingVersion(1, 0);
$Ice_Encoding_1_1 = new Ice\EncodingVersion(1, 1);
-IcePHP_defineOperation($Ice__t_Object, 'ice_isA', 2, 1, 0, array(array($IcePHP__t_string, false, 0)), null, array($IcePHP__t_bool, false, 0), null);
-IcePHP_defineOperation($Ice__t_Object, 'ice_ping', 2, 1, 0, null, null, null, null);
-IcePHP_defineOperation($Ice__t_Object, 'ice_id', 2, 1, 0, null, null, array($IcePHP__t_string, false, 0), null);
-IcePHP_defineOperation($Ice__t_Object, 'ice_ids', 2, 1, 0, null, null, array($Ice__t_StringSeq, false, 0), null);
+IcePHP_defineOperation($Ice__t_ObjectPrx, 'ice_isA', 2, 1, 0, array(array($IcePHP__t_string)), null, array($IcePHP__t_bool), null);
+IcePHP_defineOperation($Ice__t_ObjectPrx, 'ice_ping', 2, 1, 0, null, null, null, null);
+IcePHP_defineOperation($Ice__t_ObjectPrx, 'ice_id', 2, 1, 0, null, null, array($IcePHP__t_string), null);
+IcePHP_defineOperation($Ice__t_ObjectPrx, 'ice_ids', 2, 1, 0, null, null, array($Ice__t_StringSeq), null);
}
namespace Ice
diff --git a/php/src/php5/Communicator.cpp b/php/src/php5/Communicator.cpp
index 2d8fcc0b919..c22723e53d7 100644
--- a/php/src/php5/Communicator.cpp
+++ b/php/src/php5/Communicator.cpp
@@ -354,7 +354,7 @@ ZEND_METHOD(Ice_Communicator, proxyToString)
if(zv)
{
Ice::ObjectPrx prx;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(!fetchProxy(zv, prx, info TSRMLS_CC))
{
RETURN_NULL();
@@ -420,7 +420,7 @@ ZEND_METHOD(Ice_Communicator, proxyToProperty)
if(zv)
{
Ice::ObjectPrx prx;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(!fetchProxy(zv, prx, info TSRMLS_CC))
{
RETURN_NULL();
@@ -664,7 +664,7 @@ ZEND_METHOD(Ice_Communicator, getDefaultRouter)
Ice::RouterPrx router = _this->getCommunicator()->getDefaultRouter();
if(router)
{
- ClassInfoPtr info = getClassInfoById("::Ice::Router" TSRMLS_CC);
+ ProxyInfoPtr info = getProxyInfo("::Ice::Router" TSRMLS_CC);
if(!info)
{
runtimeError("no definition for Ice::Router" TSRMLS_CC);
@@ -700,7 +700,7 @@ ZEND_METHOD(Ice_Communicator, setDefaultRouter)
}
Ice::ObjectPrx proxy;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(zv && !fetchProxy(zv, proxy, info TSRMLS_CC))
{
RETURN_NULL();
@@ -742,7 +742,7 @@ ZEND_METHOD(Ice_Communicator, getDefaultLocator)
Ice::LocatorPrx locator = _this->getCommunicator()->getDefaultLocator();
if(locator)
{
- ClassInfoPtr info = getClassInfoById("::Ice::Locator" TSRMLS_CC);
+ ProxyInfoPtr info = getProxyInfo("::Ice::Locator" TSRMLS_CC);
if(!info)
{
runtimeError("no definition for Ice::Locator" TSRMLS_CC);
@@ -778,7 +778,7 @@ ZEND_METHOD(Ice_Communicator, setDefaultLocator)
}
Ice::ObjectPrx proxy;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(zv && !fetchProxy(zv, proxy, info TSRMLS_CC))
{
RETURN_NULL();
@@ -1850,7 +1850,7 @@ IcePHP::FactoryWrapper::create(const string& id)
// When the ID is that of Ice::Object, it indicates that the stream has not
// found a factory and is providing us an opportunity to preserve the object.
//
- cls = getClassInfoById("::Ice::UnknownSlicedObject" TSRMLS_CC);
+ cls = getClassInfoById("::Ice::UnknownSlicedValue" TSRMLS_CC);
}
else
{
@@ -1961,7 +1961,7 @@ IcePHP::DefaultValueFactory::create(const string& id)
// When the ID is that of Ice::Object, it indicates that the stream has not
// found a factory and is providing us an opportunity to preserve the object.
//
- cls = getClassInfoById("::Ice::UnknownSlicedObject" TSRMLS_CC);
+ cls = getClassInfoById("::Ice::UnknownSlicedValue" TSRMLS_CC);
}
else
{
@@ -1974,14 +1974,6 @@ IcePHP::DefaultValueFactory::create(const string& id)
}
//
- // If the requested type is an abstract class, then we give up.
- //
- if(cls->isAbstract)
- {
- return 0;
- }
-
- //
// Instantiate the object.
//
zval* obj;
diff --git a/php/src/php5/Operation.cpp b/php/src/php5/Operation.cpp
index 0117b62a9ed..ede0a594807 100644
--- a/php/src/php5/Operation.cpp
+++ b/php/src/php5/Operation.cpp
@@ -390,19 +390,19 @@ IcePHP::OperationI::convertParam(zval* p, int pos TSRMLS_DC)
{
assert(Z_TYPE_P(p) == IS_ARRAY);
HashTable* arr = Z_ARRVAL_P(p);
- assert(zend_hash_num_elements(arr) == 3);
ParamInfoPtr param = new ParamInfo;
zval** m;
zend_hash_index_find(arr, 0, reinterpret_cast<void**>(&m));
param->type = Wrapper<TypeInfoPtr>::value(*m TSRMLS_CC);
- zend_hash_index_find(arr, 1, reinterpret_cast<void**>(&m));
- assert(Z_TYPE_PP(m) == IS_BOOL);
- param->optional = Z_BVAL_PP(m) ? true : false;
- zend_hash_index_find(arr, 2, reinterpret_cast<void**>(&m));
- assert(Z_TYPE_PP(m) == IS_LONG);
- param->tag = Z_LVAL_PP(m);
+ param->optional = zend_hash_num_elements(arr) > 1;
+ if(param->optional)
+ {
+ zend_hash_index_find(arr, 1, reinterpret_cast<void**>(&m));
+ assert(Z_TYPE_PP(m) == IS_LONG);
+ param->tag = Z_LVAL_PP(m);
+ }
param->pos = pos;
return param;
@@ -875,11 +875,13 @@ ZEND_FUNCTION(IcePHP_defineOperation)
}
TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(cls TSRMLS_CC);
- ClassInfoPtr c = ClassInfoPtr::dynamicCast(type);
+ ProxyInfoPtr c = ProxyInfoPtr::dynamicCast(type);
assert(c);
- OperationIPtr op = new OperationI(name, static_cast<Ice::OperationMode>(mode),
- static_cast<Ice::OperationMode>(sendMode), static_cast<Ice::FormatType>(format),
+ OperationIPtr op = new OperationI(name,
+ static_cast<Ice::OperationMode>(mode),
+ static_cast<Ice::OperationMode>(sendMode),
+ static_cast<Ice::FormatType>(format),
inParams, outParams, returnType, exceptions TSRMLS_CC);
c->addOperation(name, op);
@@ -888,17 +890,17 @@ ZEND_FUNCTION(IcePHP_defineOperation)
ZEND_FUNCTION(IcePHP_Operation_call)
{
Ice::ObjectPrx proxy;
- ClassInfoPtr cls;
+ ProxyInfoPtr info;
CommunicatorInfoPtr comm;
#ifndef NDEBUG
bool b =
#endif
- fetchProxy(getThis(), proxy, cls, comm TSRMLS_CC);
+ fetchProxy(getThis(), proxy, info, comm TSRMLS_CC);
assert(b);
assert(proxy);
- assert(cls);
+ assert(info);
- OperationPtr op = cls->getOperation(get_active_function_name(TSRMLS_C));
+ OperationPtr op = info->getOperation(get_active_function_name(TSRMLS_C));
assert(op); // handleGetMethod should have already verified the operation's existence.
OperationIPtr opi = OperationIPtr::dynamicCast(op);
assert(opi);
diff --git a/php/src/php5/Proxy.cpp b/php/src/php5/Proxy.cpp
index 48c30c2782e..d9f60b79d2a 100644
--- a/php/src/php5/Proxy.cpp
+++ b/php/src/php5/Proxy.cpp
@@ -67,8 +67,6 @@ static union _zend_function* handleGetMethod(zval**, char*, int, const _zend_lit
static int handleCompare(zval*, zval* TSRMLS_DC);
}
-static ClassInfoPtr lookupClass(const string& TSRMLS_DC);
-
namespace IcePHP
{
@@ -79,15 +77,15 @@ class Proxy : public IceUtil::Shared
{
public:
- Proxy(const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
+ Proxy(const Ice::ObjectPrx&, const ProxyInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
~Proxy();
bool clone(zval*, const Ice::ObjectPrx& TSRMLS_DC);
bool cloneUntyped(zval*, const Ice::ObjectPrx& TSRMLS_DC);
- static bool create(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
+ static bool create(zval*, const Ice::ObjectPrx&, const ProxyInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
Ice::ObjectPrx proxy;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
CommunicatorInfoPtr communicator;
zval* connection;
zval* cachedConnection;
@@ -763,7 +761,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_getRouter)
Ice::RouterPrx router = _this->proxy->ice_getRouter();
if(router)
{
- ClassInfoPtr info = lookupClass("::Ice::Router" TSRMLS_CC);
+ ProxyInfoPtr info = getProxyInfo("::Ice::Router" TSRMLS_CC);
if(!info)
{
RETURN_NULL();
@@ -801,7 +799,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_router)
}
Ice::ObjectPrx proxy;
- ClassInfoPtr def;
+ ProxyInfoPtr def;
if(zprx && !fetchProxy(zprx, proxy, def TSRMLS_CC))
{
RETURN_NULL();
@@ -847,7 +845,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_getLocator)
Ice::LocatorPrx locator = _this->proxy->ice_getLocator();
if(locator)
{
- ClassInfoPtr info = lookupClass("::Ice::Locator" TSRMLS_CC);
+ ProxyInfoPtr info = getProxyInfo("::Ice::Locator" TSRMLS_CC);
if(!info)
{
RETURN_NULL();
@@ -883,7 +881,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_locator)
}
Ice::ObjectPrx proxy;
- ClassInfoPtr def;
+ ProxyInfoPtr def;
if(zprx && !fetchProxy(zprx, proxy, def TSRMLS_CC))
{
RETURN_NULL();
@@ -1290,30 +1288,6 @@ ZEND_METHOD(Ice_ObjectPrx, ice_flushBatchRequests)
}
}
-static ClassInfoPtr
-lookupClass(const string& id TSRMLS_DC)
-{
- ClassInfoPtr info = getClassInfoById(id TSRMLS_CC);
- if(!info)
- {
- if(!id.empty() && id[id.size() - 1] == '*')
- {
- info = getClassInfoById(id.substr(0, id.size() - 1) TSRMLS_CC);
- }
- }
-
- if(info && !info->defined)
- {
- runtimeError("%s is declared but not defined" TSRMLS_CC, id.c_str());
- }
- else if(!info)
- {
- runtimeError("no definition found for class or interface %s" TSRMLS_CC, id.c_str());
- }
-
- return info;
-}
-
static void
do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
{
@@ -1359,7 +1333,7 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
try
{
- ClassInfoPtr info = lookupClass(id TSRMLS_CC);
+ ProxyInfoPtr info = getProxyInfo(id TSRMLS_CC);
if(!info)
{
RETURN_NULL();
@@ -1413,7 +1387,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_checkedCast)
do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
}
-IcePHP::Proxy::Proxy(const Ice::ObjectPrx& p, const ClassInfoPtr& i, const CommunicatorInfoPtr& comm TSRMLS_DC) :
+IcePHP::Proxy::Proxy(const Ice::ObjectPrx& p, const ProxyInfoPtr& i, const CommunicatorInfoPtr& comm TSRMLS_DC) :
proxy(p), info(i), communicator(comm), connection(0), cachedConnection(0)
{
#ifdef ZTS
@@ -1453,14 +1427,14 @@ IcePHP::Proxy::cloneUntyped(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC)
}
bool
-IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm
+IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ProxyInfoPtr& info, const CommunicatorInfoPtr& comm
TSRMLS_DC)
{
- ClassInfoPtr cls = info;
- if(!cls)
+ ProxyInfoPtr prx = info;
+ if(!prx)
{
- cls = getClassInfoById("::Ice::Object" TSRMLS_CC);
- assert(cls);
+ prx = getProxyInfo("::Ice::Object" TSRMLS_CC);
+ assert(prx);
}
if(object_init_ex(zv, proxyClassEntry) != SUCCESS)
@@ -1470,7 +1444,7 @@ IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& inf
}
Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv TSRMLS_CC);
- ProxyPtr proxy = new Proxy(p, cls, comm TSRMLS_CC);
+ ProxyPtr proxy = new Proxy(p, prx, comm TSRMLS_CC);
assert(!obj->ptr);
obj->ptr = new ProxyPtr(proxy);
@@ -1571,7 +1545,7 @@ handleGetMethod(zval** zv, char* method, int len, const _zend_literal* key TSRML
assert(obj->ptr);
ProxyPtr _this = *obj->ptr;
- ClassInfoPtr info = _this->info;
+ ProxyInfoPtr info = _this->info;
assert(info);
OperationPtr op = info->getOperation(method);
@@ -1724,21 +1698,21 @@ IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const CommunicatorInfoPtr
}
bool
-IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm
+IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const ProxyInfoPtr& info, const CommunicatorInfoPtr& comm
TSRMLS_DC)
{
return Proxy::create(zv, p, info, comm TSRMLS_CC);
}
bool
-IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls TSRMLS_DC)
+IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ProxyInfoPtr& info TSRMLS_DC)
{
CommunicatorInfoPtr comm;
- return fetchProxy(zv, prx, cls, comm TSRMLS_CC);
+ return fetchProxy(zv, prx, info, comm TSRMLS_CC);
}
bool
-IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls, CommunicatorInfoPtr& comm TSRMLS_DC)
+IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ProxyInfoPtr& info, CommunicatorInfoPtr& comm TSRMLS_DC)
{
if(!ZVAL_IS_NULL(zv))
{
@@ -1755,7 +1729,7 @@ IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls, Communicato
}
assert(obj->ptr);
prx = (*obj->ptr)->proxy;
- cls = (*obj->ptr)->info;
+ info = (*obj->ptr)->info;
comm = (*obj->ptr)->communicator;
}
return true;
diff --git a/php/src/php5/Proxy.h b/php/src/php5/Proxy.h
index 235a427c2f5..4becbbdd906 100644
--- a/php/src/php5/Proxy.h
+++ b/php/src/php5/Proxy.h
@@ -20,9 +20,9 @@ namespace IcePHP
bool proxyInit(TSRMLS_D);
bool createProxy(zval*, const Ice::ObjectPrx&, const CommunicatorInfoPtr& TSRMLS_DC);
-bool createProxy(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
-bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr& TSRMLS_DC);
-bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr&, CommunicatorInfoPtr& TSRMLS_DC);
+bool createProxy(zval*, const Ice::ObjectPrx&, const ProxyInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
+bool fetchProxy(zval*, Ice::ObjectPrx&, ProxyInfoPtr& TSRMLS_DC);
+bool fetchProxy(zval*, Ice::ObjectPrx&, ProxyInfoPtr&, CommunicatorInfoPtr& TSRMLS_DC);
//
// Class entry.
diff --git a/php/src/php5/Types.cpp b/php/src/php5/Types.cpp
index 188c512552f..93d9f655b24 100644
--- a/php/src/php5/Types.cpp
+++ b/php/src/php5/Types.cpp
@@ -75,8 +75,8 @@ addProxyInfo(const ProxyInfoPtr& p TSRMLS_DC)
//
// getProxyInfo()
//
-static IcePHP::ProxyInfoPtr
-getProxyInfo(const string& id TSRMLS_DC)
+IcePHP::ProxyInfoPtr
+IcePHP::getProxyInfo(const string& id TSRMLS_DC)
{
if(ICE_G(proxyInfoMap))
{
@@ -2487,17 +2487,17 @@ IcePHP::DictionaryInfo::destroy()
// ClassInfo implementation.
//
IcePHP::ClassInfo::ClassInfo(const string& ident TSRMLS_DC) :
- id(ident), compactId(-1), isAbstract(false), preserve(false), zce(0), defined(false)
+ id(ident), compactId(-1), preserve(false), interface(false), zce(0), defined(false)
{
}
void
-IcePHP::ClassInfo::define(const string& n, Ice::Int compact, bool isAbs, bool pres, zval* b, zval* i, zval* m TSRMLS_DC)
+IcePHP::ClassInfo::define(const string& n, Ice::Int compact, bool pres, bool intf, zval* b, zval* m TSRMLS_DC)
{
const_cast<string&>(name) = n;
const_cast<Ice::Int&>(compactId) = static_cast<Ice::Int>(compact);
- const_cast<bool&>(isAbstract) = isAbs;
const_cast<bool&>(preserve) = pres;
+ const_cast<bool&>(interface) = intf;
if(b)
{
@@ -2506,23 +2506,6 @@ IcePHP::ClassInfo::define(const string& n, Ice::Int compact, bool isAbs, bool pr
assert(base);
}
- if(i)
- {
- HashTable* interfacesArray = Z_ARRVAL_P(i);
- void* data;
- HashPosition pos;
- zend_hash_internal_pointer_reset_ex(interfacesArray, &pos);
- while(zend_hash_get_current_data_ex(interfacesArray, &data, &pos) != FAILURE)
- {
- zval** interfaceType = reinterpret_cast<zval**>(data);
- TypeInfoPtr t = Wrapper<TypeInfoPtr>::value(*interfaceType TSRMLS_CC);
- ClassInfoPtr c = ClassInfoPtr::dynamicCast(t);
- assert(c);
- const_cast<ClassInfoList&>(interfaces).push_back(c);
- zend_hash_move_forward_ex(interfacesArray, &pos);
- }
- }
-
if(m)
{
convertDataMembers(m, const_cast<DataMemberList&>(members), const_cast<DataMemberList&>(optionalMembers),
@@ -2530,8 +2513,14 @@ IcePHP::ClassInfo::define(const string& n, Ice::Int compact, bool isAbs, bool pr
}
const_cast<bool&>(defined) = true;
- const_cast<zend_class_entry*&>(zce) = nameToClass(name TSRMLS_CC);
- assert(zce || id == "::Ice::LocalObject"); // LocalObject does not have a native PHP equivalent.
+#ifdef ICEPHP_USE_NAMESPACES
+ const string valueClass = "Ice\\Value";
+#else
+ const string valueClass = "Ice_Value";
+#endif
+ const_cast<zend_class_entry*&>(zce) = nameToClass(interface ? valueClass : name TSRMLS_CC);
+ // LocalObject and interfaces does not have a native PHP equivalent.
+ assert(zce || id == "::Ice::LocalObject" || interface);
}
string
@@ -2689,7 +2678,6 @@ void
IcePHP::ClassInfo::destroy()
{
const_cast<ClassInfoPtr&>(base) = 0;
- const_cast<ClassInfoList&>(interfaces).clear();
if(!members.empty())
{
DataMemberList ml = members;
@@ -2761,63 +2749,44 @@ IcePHP::ClassInfo::isA(const string& typeId) const
return true;
}
- if(base && base->isA(typeId))
- {
- return true;
- }
-
- for(ClassInfoList::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
- {
- if((*p)->isA(typeId))
- {
- return true;
- }
- }
-
- return false;
+ return base && base->isA(typeId);
}
-void
-IcePHP::ClassInfo::addOperation(const string& name, const OperationPtr& op)
+//
+// ProxyInfo implementation.
+//
+IcePHP::ProxyInfo::ProxyInfo(const string& ident TSRMLS_DC) :
+ id(ident), defined(false)
{
- operations.insert(OperationMap::value_type(Slice::PHP::fixIdent(name), op));
}
-IcePHP::OperationPtr
-IcePHP::ClassInfo::getOperation(const string& name) const
+void
+IcePHP::ProxyInfo::define(zval* b, zval* i TSRMLS_DC)
{
- OperationPtr op;
- OperationMap::const_iterator p = operations.find(name);
- if(p != operations.end())
- {
- op = p->second;
- }
- if(!op && base)
+ if(b)
{
- op = base->getOperation(name);
+ TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(b);
+ const_cast<ProxyInfoPtr&>(base) = ProxyInfoPtr::dynamicCast(p);
+ assert(base);
}
- if(!op && !interfaces.empty())
+
+ if(i)
{
- for(ClassInfoList::const_iterator q = interfaces.begin(); q != interfaces.end() && !op; ++q)
+ HashTable* interfacesArray = Z_ARRVAL_P(i);
+ void* data;
+ HashPosition pos;
+ zend_hash_internal_pointer_reset_ex(interfacesArray, &pos);
+ while(zend_hash_get_current_data_ex(interfacesArray, &data, &pos) != FAILURE)
{
- op = (*q)->getOperation(name);
+ zval** interfaceType = reinterpret_cast<zval**>(data);
+ TypeInfoPtr t = Wrapper<TypeInfoPtr>::value(*interfaceType TSRMLS_CC);
+ ProxyInfoPtr c = ProxyInfoPtr::dynamicCast(t);
+ assert(c);
+ const_cast<ProxyInfoList&>(interfaces).push_back(c);
+ zend_hash_move_forward_ex(interfacesArray, &pos);
}
}
- return op;
-}
-//
-// ProxyInfo implementation.
-//
-IcePHP::ProxyInfo::ProxyInfo(const string& ident TSRMLS_DC) :
- id(ident), defined(false)
-{
-}
-
-void
-IcePHP::ProxyInfo::define(const ClassInfoPtr& c TSRMLS_DC)
-{
- const_cast<ClassInfoPtr&>(cls) = c;
const_cast<bool&>(defined) = true;
}
@@ -2881,7 +2850,7 @@ IcePHP::ProxyInfo::marshal(zval* zv, Ice::OutputStream* os, ObjectMap*, bool opt
{
assert(Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == proxyClassEntry); // validate() should have caught this.
Ice::ObjectPrx proxy;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(!fetchProxy(zv, proxy, info TSRMLS_CC))
{
throw AbortMarshaling();
@@ -2923,13 +2892,13 @@ IcePHP::ProxyInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& c
return;
}
- if(!cls->defined)
+ if(!defined)
{
- runtimeError("class or interface %s is declared but not defined" TSRMLS_CC, id.c_str());
+ runtimeError("proxy %s is declared but not defined" TSRMLS_CC, id.c_str());
throw AbortMarshaling();
}
- if(!createProxy(zv, proxy, cls, comm TSRMLS_CC))
+ if(!createProxy(zv, proxy, this, comm TSRMLS_CC))
{
throw AbortMarshaling();
}
@@ -2952,8 +2921,8 @@ IcePHP::ProxyInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHist
else
{
Ice::ObjectPrx proxy;
- ClassInfoPtr cls;
- if(!fetchProxy(zv, proxy, cls TSRMLS_CC))
+ ProxyInfoPtr info;
+ if(!fetchProxy(zv, proxy, info TSRMLS_CC))
{
return;
}
@@ -2964,14 +2933,68 @@ IcePHP::ProxyInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHist
void
IcePHP::ProxyInfo::destroy()
{
- const_cast<ClassInfoPtr&>(cls) = 0;
+ const_cast<ProxyInfoPtr&>(base) = 0;
+ const_cast<ProxyInfoList&>(interfaces).clear();
+}
+
+bool
+IcePHP::ProxyInfo::isA(const string& typeId) const
+{
+ if(id == typeId)
+ {
+ return true;
+ }
+
+ if(base && base->isA(typeId))
+ {
+ return true;
+ }
+
+ for(ProxyInfoList::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
+ {
+ if((*p)->isA(typeId))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+IcePHP::ProxyInfo::addOperation(const string& name, const OperationPtr& op)
+{
+ operations.insert(OperationMap::value_type(Slice::PHP::fixIdent(name), op));
+}
+
+IcePHP::OperationPtr
+IcePHP::ProxyInfo::getOperation(const string& name) const
+{
+ OperationPtr op;
+ OperationMap::const_iterator p = operations.find(name);
+ if(p != operations.end())
+ {
+ op = p->second;
+ }
+ if(!op && base)
+ {
+ op = base->getOperation(name);
+ }
+ if(!op && !interfaces.empty())
+ {
+ for(ProxyInfoList::const_iterator q = interfaces.begin(); q != interfaces.end() && !op; ++q)
+ {
+ op = (*q)->getOperation(name);
+ }
+ }
+ return op;
}
//
// ObjectWriter implementation.
//
IcePHP::ObjectWriter::ObjectWriter(zval* object, ObjectMap* objectMap, const ClassInfoPtr& formal TSRMLS_DC) :
- _object(object), _map(objectMap)
+ _object(object), _map(objectMap), _formal(formal)
{
#ifdef ZTS
this->TSRMLS_C = TSRMLS_C;
@@ -2979,15 +3002,18 @@ IcePHP::ObjectWriter::ObjectWriter(zval* object, ObjectMap* objectMap, const Cla
Z_ADDREF_P(_object);
- //
- // We need to determine the most-derived Slice type supported by this object.
- // This is typically a Slice class, but it can also be an interface.
- //
- // The caller may have provided a ClassInfo representing the formal type, in
- // which case we ensure that the actual type is compatible with the formal type.
- //
- _info = getClassInfoByClass(Z_OBJCE_P(object), formal ? const_cast<zend_class_entry*>(formal->zce) : 0 TSRMLS_CC);
- assert(_info);
+ if(!_formal || !_formal->interface)
+ {
+ //
+ // For no interface types We need to determine the most-derived Slice type supported by this object.
+ // This is typically a Slice class, but it can also be an interface.
+ //
+ // The caller may have provided a ClassInfo representing the formal type, in
+ // which case we ensure that the actual type is compatible with the formal type.
+ //
+ _info = getClassInfoByClass(Z_OBJCE_P(object), formal ? const_cast<zend_class_entry*>(formal->zce) : 0 TSRMLS_CC);
+ assert(_info);
+ }
}
IcePHP::ObjectWriter::~ObjectWriter()
@@ -3013,7 +3039,7 @@ IcePHP::ObjectWriter::_iceWrite(Ice::OutputStream* os) const
{
Ice::SlicedDataPtr slicedData;
- if(_info->preserve)
+ if(_info && _info->preserve)
{
//
// Retrieve the SlicedData object that we stored as a hidden member of the PHP object.
@@ -3023,21 +3049,64 @@ IcePHP::ObjectWriter::_iceWrite(Ice::OutputStream* os) const
os->startValue(slicedData);
- if(_info->id != "::Ice::UnknownSlicedObject")
+ if(_formal && _formal->interface)
{
- ClassInfoPtr info = _info;
- while(info && info->id != Ice::Object::ice_staticId())
+ //
+ // For an interface by value we just marshal the Ice type id
+ // of the object in its own slice.
+ //
+ zval* ret = 0;
+
+ zend_try
{
- assert(info->base); // All classes have the Ice::Object base type.
- const bool lastSlice = info->base->id == Ice::Object::ice_staticId();
- os->startSlice(info->id, info->compactId, lastSlice);
+ const char* func = "ice_id";
+ zval* obj = const_cast<zval*>(_object);
+ zend_call_method(&obj, 0, 0, const_cast<char*>(func), static_cast<int>(strlen(func)), &ret, 0, 0,
+ 0 TSRMLS_CC);
+ }
+ zend_catch
+ {
+ ret = 0;
+ }
+ zend_end_try();
- writeMembers(os, info->members);
- writeMembers(os, info->optionalMembers); // The optional members have already been sorted by tag.
+ //
+ // Bail out if an exception has already been thrown.
+ //
+ if(!ret || EG(exception))
+ {
+ throw AbortMarshaling();
+ }
- os->endSlice();
+ AutoDestroy destroy(ret);
+
+ if(Z_TYPE_P(ret) != IS_STRING)
+ {
+ throw AbortMarshaling();
+ }
- info = info->base;
+ string id(Z_STRVAL_P(ret), Z_STRLEN_P(ret));
+ os->startSlice(id, -1, true);
+ os->endSlice();
+ }
+ else
+ {
+ if(_info->id != "::Ice::UnknownSlicedValue")
+ {
+ ClassInfoPtr info = _info;
+ while(info && info->id != Ice::Object::ice_staticId())
+ {
+ assert(info->base); // All classes have the Ice::Object base type.
+ const bool lastSlice = info->base->id == Ice::Object::ice_staticId();
+ os->startSlice(info->id, info->compactId, lastSlice);
+
+ writeMembers(os, info->members);
+ writeMembers(os, info->optionalMembers); // The optional members have already been sorted by tag.
+
+ os->endSlice();
+
+ info = info->base;
+ }
}
}
@@ -3126,7 +3195,7 @@ IcePHP::ObjectReader::_iceRead(Ice::InputStream* is)
{
is->startValue();
- const bool unknown = _info->id == "::Ice::UnknownSlicedObject";
+ const bool unknown = _info->id == "::Ice::UnknownSlicedValue";
//
// Unmarshal the slices of a user-defined class.
@@ -3256,7 +3325,7 @@ IcePHP::ReadObjectCallback::invoke(const Ice::ObjectPtr& p)
// Verify that the unmarshaled object is compatible with the formal type.
//
zval* obj = reader->getObject();
- if(!reader->getInfo()->isA(_info->id))
+ if(!_info->interface && !reader->getInfo()->isA(_info->id))
{
Ice::UnexpectedObjectException ex(__FILE__, __LINE__);
ex.reason = "unmarshaled object is not an instance of " + _info->id;
@@ -3694,25 +3763,26 @@ ZEND_FUNCTION(IcePHP_declareProxy)
ZEND_FUNCTION(IcePHP_defineProxy)
{
- zval* cls;
+ char* id;
+ size_t idLen;
+ zval* base;
+ zval* interfaces;
+
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("o"), &cls) == FAILURE)
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("so!a!"), &id, &idLen, &base, &interfaces) ==
+ FAILURE)
{
return;
}
- TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(cls TSRMLS_CC);
- ClassInfoPtr c = ClassInfoPtr::dynamicCast(p);
- assert(c);
-
- ProxyInfoPtr type = getProxyInfo(c->id TSRMLS_CC);
+ ProxyInfoPtr type = getProxyInfo(id TSRMLS_CC);
if(!type)
{
- type = new ProxyInfo(c->id TSRMLS_CC);
+ type = new ProxyInfo(id TSRMLS_CC);
addProxyInfo(type TSRMLS_CC);
}
- type->define(c TSRMLS_CC);
+ type->define(base, interfaces TSRMLS_CC);
if(!createTypeInfo(return_value, type TSRMLS_CC))
{
@@ -3750,14 +3820,13 @@ ZEND_FUNCTION(IcePHP_defineClass)
char* name;
int nameLen;
long compactId;
- zend_bool isAbstract;
zend_bool preserve;
+ zend_bool interface;
zval* base;
- zval* interfaces;
zval* members;
- if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("sslbbo!a!a!"), &id, &idLen, &name, &nameLen,
- &compactId, &isAbstract, &preserve, &base, &interfaces, &members) == FAILURE)
+ if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("sslbbo!a!"), &id, &idLen, &name, &nameLen,
+ &compactId, &preserve, &interface, &base, &members) == FAILURE)
{
return;
}
@@ -3769,17 +3838,23 @@ ZEND_FUNCTION(IcePHP_defineClass)
addClassInfoById(type TSRMLS_CC);
}
- type->define(name, static_cast<Ice::Int>(compactId), isAbstract ? true : false, preserve ? true : false, base,
- interfaces, members TSRMLS_CC);
- addClassInfoByName(type TSRMLS_CC);
+ type->define(name, static_cast<Ice::Int>(compactId), preserve ? true : false, interface ? true : false, base,
+ members TSRMLS_CC);
+ if(!interface)
+ {
+ addClassInfoByName(type TSRMLS_CC);
+ }
- CompactIdMap* m = reinterpret_cast<CompactIdMap*>(ICE_G(compactIdToClassInfoMap));
- if(!m)
+ if(type->compactId != -1)
{
- m = new CompactIdMap;
- ICE_G(compactIdToClassInfoMap) = m;
+ CompactIdMap* m = reinterpret_cast<CompactIdMap*>(ICE_G(compactIdToClassInfoMap));
+ if(!m)
+ {
+ m = new CompactIdMap;
+ ICE_G(compactIdToClassInfoMap) = m;
+ }
+ m->insert(CompactIdMap::value_type(type->compactId, type));
}
- m->insert(CompactIdMap::value_type(type->compactId, type));
if(!createTypeInfo(return_value, type TSRMLS_CC))
{
diff --git a/php/src/php5/Types.h b/php/src/php5/Types.h
index 6777990217c..62309e93648 100644
--- a/php/src/php5/Types.h
+++ b/php/src/php5/Types.h
@@ -45,7 +45,10 @@ class AbortMarshaling
class ClassInfo;
typedef IceUtil::Handle<ClassInfo> ClassInfoPtr;
-typedef std::vector<ClassInfoPtr> ClassInfoList;
+
+class ProxyInfo;
+typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr;
+typedef std::vector<ProxyInfoPtr> ProxyInfoList;
typedef std::map<unsigned int, Ice::ObjectPtr> ObjectMap;
@@ -417,7 +420,7 @@ public:
ClassInfo(const std::string& TSRMLS_DC);
- void define(const std::string&, Ice::Int, bool, bool, zval*, zval*, zval* TSRMLS_DC);
+ void define(const std::string&, Ice::Int, bool, bool, zval*, zval* TSRMLS_DC);
virtual std::string getId() const;
@@ -441,23 +444,16 @@ public:
bool isA(const std::string&) const;
- void addOperation(const std::string&, const OperationPtr&);
- OperationPtr getOperation(const std::string&) const;
-
const std::string id;
const std::string name; // PHP class name
const Ice::Int compactId;
- const bool isAbstract;
const bool preserve;
+ const bool interface;
const ClassInfoPtr base;
- const ClassInfoList interfaces;
const DataMemberList members;
const DataMemberList optionalMembers;
const zend_class_entry* zce;
bool defined;
-
- typedef std::map<std::string, OperationPtr> OperationMap;
- OperationMap operations;
};
//
@@ -469,7 +465,7 @@ public:
ProxyInfo(const std::string& TSRMLS_DC);
- void define(const ClassInfoPtr& TSRMLS_DC);
+ void define(zval*, zval* TSRMLS_DC);
virtual std::string getId() const;
@@ -487,9 +483,17 @@ public:
virtual void destroy();
+ bool isA(const std::string&) const;
+
+ void addOperation(const std::string&, const OperationPtr&);
+ OperationPtr getOperation(const std::string&) const;
+
const std::string id;
- const ClassInfoPtr cls;
+ const ProxyInfoPtr base;
+ const ProxyInfoList interfaces;
bool defined;
+ typedef std::map<std::string, OperationPtr> OperationMap;
+ OperationMap operations;
};
typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr;
@@ -519,6 +523,7 @@ public:
ClassInfoPtr getClassInfoById(const std::string& TSRMLS_DC);
ClassInfoPtr getClassInfoByName(const std::string& TSRMLS_DC);
+ProxyInfoPtr getProxyInfo(const std::string& TSRMLS_DC);
ExceptionInfoPtr getExceptionInfo(const std::string& TSRMLS_DC);
bool isUnset(zval* TSRMLS_DC);
@@ -550,6 +555,7 @@ private:
zval* _object;
ObjectMap* _map;
ClassInfoPtr _info;
+ ClassInfoPtr _formal;
#if ZTS
TSRMLS_D;
#endif
diff --git a/php/src/php7/Communicator.cpp b/php/src/php7/Communicator.cpp
index 18a080b1d66..b707cf962c6 100644
--- a/php/src/php7/Communicator.cpp
+++ b/php/src/php7/Communicator.cpp
@@ -21,7 +21,7 @@
#include <fstream>
#ifdef getcwd
-#undef getcwd
+# undef getcwd
#endif
#include <IceUtil/FileUtil.h>
@@ -360,7 +360,7 @@ ZEND_METHOD(Ice_Communicator, proxyToString)
if(zv)
{
Ice::ObjectPrx prx;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(!fetchProxy(zv, prx, info))
{
RETURN_NULL();
@@ -426,7 +426,7 @@ ZEND_METHOD(Ice_Communicator, proxyToProperty)
if(zv)
{
Ice::ObjectPrx prx;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(!fetchProxy(zv, prx, info))
{
RETURN_NULL();
@@ -670,7 +670,7 @@ ZEND_METHOD(Ice_Communicator, getDefaultRouter)
Ice::RouterPrx router = _this->getCommunicator()->getDefaultRouter();
if(router)
{
- ClassInfoPtr info = getClassInfoById("::Ice::Router");
+ ProxyInfoPtr info = getProxyInfo("::Ice::Router");
if(!info)
{
runtimeError("no definition for Ice::Router");
@@ -706,7 +706,7 @@ ZEND_METHOD(Ice_Communicator, setDefaultRouter)
}
Ice::ObjectPrx proxy;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(zv && !fetchProxy(zv, proxy, info))
{
RETURN_NULL();
@@ -748,7 +748,7 @@ ZEND_METHOD(Ice_Communicator, getDefaultLocator)
Ice::LocatorPrx locator = _this->getCommunicator()->getDefaultLocator();
if(locator)
{
- ClassInfoPtr info = getClassInfoById("::Ice::Locator");
+ ProxyInfoPtr info = getProxyInfo("::Ice::Locator");
if(!info)
{
runtimeError("no definition for Ice::Locator");
@@ -784,7 +784,7 @@ ZEND_METHOD(Ice_Communicator, setDefaultLocator)
}
Ice::ObjectPrx proxy;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(zv && !fetchProxy(zv, proxy, info))
{
RETURN_NULL();
@@ -1855,7 +1855,7 @@ IcePHP::FactoryWrapper::create(const string& id)
// When the ID is that of Ice::Object, it indicates that the stream has not
// found a factory and is providing us an opportunity to preserve the object.
//
- cls = getClassInfoById("::Ice::UnknownSlicedObject");
+ cls = getClassInfoById("::Ice::UnknownSlicedValue");
}
else
{
@@ -1940,7 +1940,6 @@ IcePHP::DefaultValueFactory::create(const string& id)
//
// Get the TSRM id for the current request.
//
-
if(_delegate)
{
Ice::ValuePtr v = _delegate->create(id);
@@ -1960,7 +1959,7 @@ IcePHP::DefaultValueFactory::create(const string& id)
// When the ID is that of Ice::Object, it indicates that the stream has not
// found a factory and is providing us an opportunity to preserve the object.
//
- cls = getClassInfoById("::Ice::UnknownSlicedObject");
+ cls = getClassInfoById("::Ice::UnknownSlicedValue");
}
else
{
@@ -1973,14 +1972,6 @@ IcePHP::DefaultValueFactory::create(const string& id)
}
//
- // If the requested type is an abstract class, then we give up.
- //
- if(cls->isAbstract)
- {
- return 0;
- }
-
- //
// Instantiate the object.
//
zval obj;
@@ -2068,7 +2059,6 @@ IcePHP::CommunicatorInfoI::addFactory(zval* factory, const string& id, bool isOb
throwException(ex);
return false;
}
-
_factories.insert(FactoryMap::value_type(id, new FactoryWrapper(factory, isObjectFactory, this)));
}
@@ -2091,7 +2081,6 @@ IcePHP::CommunicatorInfoI::findFactory(const string& id) const
return p->second;
}
}
-
return 0;
}
diff --git a/php/src/php7/Operation.cpp b/php/src/php7/Operation.cpp
index e4afea75a8d..2e9c91b29f6 100644
--- a/php/src/php7/Operation.cpp
+++ b/php/src/php7/Operation.cpp
@@ -368,13 +368,13 @@ IcePHP::OperationI::convertParam(zval* p, int pos)
ParamInfoPtr param = new ParamInfo;
param->type = Wrapper<TypeInfoPtr>::value(zend_hash_index_find(arr, 0));
+ param->optional = zend_hash_num_elements(arr) > 1;
- assert(Z_TYPE_P(zend_hash_index_find(arr, 1)) == IS_TRUE || Z_TYPE_P(zend_hash_index_find(arr, 1)) == IS_FALSE);
- param->optional = Z_TYPE_P(zend_hash_index_find(arr, 1)) == IS_TRUE;
-
- assert(Z_TYPE_P(zend_hash_index_find(arr, 2)) == IS_LONG);
- param->tag = static_cast<int>(Z_LVAL_P(zend_hash_index_find(arr, 2)));
-
+ if(param->optional)
+ {
+ assert(Z_TYPE_P(zend_hash_index_find(arr, 1)) == IS_LONG);
+ param->tag = static_cast<int>(Z_LVAL_P(zend_hash_index_find(arr, 1)));
+ }
param->pos = pos;
return param;
@@ -840,11 +840,13 @@ ZEND_FUNCTION(IcePHP_defineOperation)
}
TypeInfoPtr type = Wrapper<TypeInfoPtr>::value(cls);
- ClassInfoPtr c = ClassInfoPtr::dynamicCast(type);
+ ProxyInfoPtr c = ProxyInfoPtr::dynamicCast(type);
assert(c);
- OperationIPtr op = new OperationI(name, static_cast<Ice::OperationMode>(mode),
- static_cast<Ice::OperationMode>(sendMode), static_cast<Ice::FormatType>(format),
+ OperationIPtr op = new OperationI(name,
+ static_cast<Ice::OperationMode>(mode),
+ static_cast<Ice::OperationMode>(sendMode),
+ static_cast<Ice::FormatType>(format),
inParams, outParams, returnType, exceptions);
c->addOperation(name, op);
@@ -853,17 +855,17 @@ ZEND_FUNCTION(IcePHP_defineOperation)
ZEND_FUNCTION(IcePHP_Operation_call)
{
Ice::ObjectPrx proxy;
- ClassInfoPtr cls;
+ ProxyInfoPtr info;
CommunicatorInfoPtr comm;
#ifndef NDEBUG
bool b =
#endif
- fetchProxy(getThis(), proxy, cls, comm);
+ fetchProxy(getThis(), proxy, info, comm);
assert(b);
assert(proxy);
- assert(cls);
+ assert(info);
- OperationPtr op = cls->getOperation(get_active_function_name());
+ OperationPtr op = info->getOperation(get_active_function_name());
assert(op); // handleGetMethod should have already verified the operation's existence.
OperationIPtr opi = OperationIPtr::dynamicCast(op);
assert(opi);
diff --git a/php/src/php7/Proxy.cpp b/php/src/php7/Proxy.cpp
index 99a722d7e21..c3675f89f47 100644
--- a/php/src/php7/Proxy.cpp
+++ b/php/src/php7/Proxy.cpp
@@ -63,8 +63,6 @@ static union _zend_function* handleGetMethod(zend_object**, zend_string*, const
static int handleCompare(zval*, zval*);
}
-static ClassInfoPtr lookupClass(const string&);
-
namespace IcePHP
{
@@ -75,15 +73,15 @@ class Proxy : public IceUtil::Shared
{
public:
- Proxy(const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr&);
+ Proxy(const Ice::ObjectPrx&, const ProxyInfoPtr&, const CommunicatorInfoPtr&);
~Proxy();
bool clone(zval*, const Ice::ObjectPrx&);
bool cloneUntyped(zval*, const Ice::ObjectPrx&);
- static bool create(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr&);
+ static bool create(zval*, const Ice::ObjectPrx&, const ProxyInfoPtr&, const CommunicatorInfoPtr&);
Ice::ObjectPrx proxy;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
CommunicatorInfoPtr communicator;
zval* connection;
zval* cachedConnection;
@@ -750,7 +748,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_getRouter)
Ice::RouterPrx router = _this->proxy->ice_getRouter();
if(router)
{
- ClassInfoPtr info = lookupClass("::Ice::Router");
+ ProxyInfoPtr info = getProxyInfo("::Ice::Router");
if(!info)
{
RETURN_NULL();
@@ -788,7 +786,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_router)
}
Ice::ObjectPrx proxy;
- ClassInfoPtr def;
+ ProxyInfoPtr def;
if(zprx && !fetchProxy(zprx, proxy, def))
{
RETURN_NULL();
@@ -834,7 +832,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_getLocator)
Ice::LocatorPrx locator = _this->proxy->ice_getLocator();
if(locator)
{
- ClassInfoPtr info = lookupClass("::Ice::Locator");
+ ProxyInfoPtr info = getProxyInfo("::Ice::Locator");
if(!info)
{
RETURN_NULL();
@@ -870,7 +868,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_locator)
}
Ice::ObjectPrx proxy;
- ClassInfoPtr def;
+ ProxyInfoPtr def;
if(zprx && !fetchProxy(zprx, proxy, def))
{
RETURN_NULL();
@@ -1277,30 +1275,6 @@ ZEND_METHOD(Ice_ObjectPrx, ice_flushBatchRequests)
}
}
-static ClassInfoPtr
-lookupClass(const string& id)
-{
- ClassInfoPtr info = getClassInfoById(id);
- if(!info)
- {
- if(!id.empty() && id[id.size() - 1] == '*')
- {
- info = getClassInfoById(id.substr(0, id.size() - 1));
- }
- }
-
- if(info && !info->defined)
- {
- runtimeError("%s is declared but not defined", id.c_str());
- }
- else if(!info)
- {
- runtimeError("no definition found for class or interface %s", id.c_str());
- }
-
- return info;
-}
-
static void
do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
{
@@ -1346,7 +1320,7 @@ do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
try
{
- ClassInfoPtr info = lookupClass(id);
+ ProxyInfoPtr info = getProxyInfo(id);
if(!info)
{
RETURN_NULL();
@@ -1400,7 +1374,7 @@ ZEND_METHOD(Ice_ObjectPrx, ice_checkedCast)
do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
}
-IcePHP::Proxy::Proxy(const Ice::ObjectPrx& p, const ClassInfoPtr& i, const CommunicatorInfoPtr& comm) :
+IcePHP::Proxy::Proxy(const Ice::ObjectPrx& p, const ProxyInfoPtr& i, const CommunicatorInfoPtr& comm) :
proxy(p), info(i), communicator(comm), connection(0), cachedConnection(0)
{
//
@@ -1436,14 +1410,13 @@ IcePHP::Proxy::cloneUntyped(zval* zv, const Ice::ObjectPrx& p)
}
bool
-IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm
- )
+IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ProxyInfoPtr& info, const CommunicatorInfoPtr& comm)
{
- ClassInfoPtr cls = info;
- if(!cls)
+ ProxyInfoPtr prx = info;
+ if(!prx)
{
- cls = getClassInfoById("::Ice::Object");
- assert(cls);
+ prx = getProxyInfo("::Ice::Object");
+ assert(prx);
}
if(object_init_ex(zv, proxyClassEntry) != SUCCESS)
@@ -1453,7 +1426,7 @@ IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& inf
}
Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv);
- ProxyPtr proxy = new Proxy(p, cls, comm);
+ ProxyPtr proxy = new Proxy(p, prx, comm);
assert(!obj->ptr);
obj->ptr = new ProxyPtr(proxy);
return true;
@@ -1525,7 +1498,7 @@ handleGetMethod(zend_object **object, zend_string *name, const zval *key )
assert(obj->ptr);
ProxyPtr _this = *obj->ptr;
- ClassInfoPtr info = _this->info;
+ ProxyInfoPtr info = _this->info;
assert(info);
OperationPtr op = info->getOperation(name->val);
@@ -1680,21 +1653,21 @@ IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const CommunicatorInfoPtr
}
bool
-IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const ClassInfoPtr& info, const CommunicatorInfoPtr& comm
+IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const ProxyInfoPtr& info, const CommunicatorInfoPtr& comm
)
{
return Proxy::create(zv, p, info, comm);
}
bool
-IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls)
+IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ProxyInfoPtr& info)
{
CommunicatorInfoPtr comm;
- return fetchProxy(zv, prx, cls, comm);
+ return fetchProxy(zv, prx, info, comm);
}
bool
-IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls, CommunicatorInfoPtr& comm)
+IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ProxyInfoPtr& info, CommunicatorInfoPtr& comm)
{
if(!ZVAL_IS_NULL(zv))
{
@@ -1711,7 +1684,7 @@ IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ClassInfoPtr& cls, Communicato
}
assert(obj->ptr);
prx = (*obj->ptr)->proxy;
- cls = (*obj->ptr)->info;
+ info = (*obj->ptr)->info;
comm = (*obj->ptr)->communicator;
}
return true;
diff --git a/php/src/php7/Proxy.h b/php/src/php7/Proxy.h
index 771e999ea88..a2b02bdc3b4 100644
--- a/php/src/php7/Proxy.h
+++ b/php/src/php7/Proxy.h
@@ -20,9 +20,9 @@ namespace IcePHP
bool proxyInit(void);
bool createProxy(zval*, const Ice::ObjectPrx&, const CommunicatorInfoPtr&);
-bool createProxy(zval*, const Ice::ObjectPrx&, const ClassInfoPtr&, const CommunicatorInfoPtr&);
-bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr&);
-bool fetchProxy(zval*, Ice::ObjectPrx&, ClassInfoPtr&, CommunicatorInfoPtr&);
+bool createProxy(zval*, const Ice::ObjectPrx&, const ProxyInfoPtr&, const CommunicatorInfoPtr&);
+bool fetchProxy(zval*, Ice::ObjectPrx&, ProxyInfoPtr&);
+bool fetchProxy(zval*, Ice::ObjectPrx&, ProxyInfoPtr&, CommunicatorInfoPtr&);
//
// Class entry.
diff --git a/php/src/php7/Types.cpp b/php/src/php7/Types.cpp
index ce454528f80..586e438ab21 100644
--- a/php/src/php7/Types.cpp
+++ b/php/src/php7/Types.cpp
@@ -75,8 +75,8 @@ addProxyInfo(const ProxyInfoPtr& p)
//
// getProxyInfo()
//
-static IcePHP::ProxyInfoPtr
-getProxyInfo(const string& id)
+IcePHP::ProxyInfoPtr
+IcePHP::getProxyInfo(const string& id)
{
if(ICE_G(proxyInfoMap))
{
@@ -2386,17 +2386,17 @@ IcePHP::DictionaryInfo::destroy()
// ClassInfo implementation.
//
IcePHP::ClassInfo::ClassInfo(const string& ident) :
- id(ident), compactId(-1), isAbstract(false), preserve(false), zce(0), defined(false)
+ id(ident), compactId(-1), preserve(false), interface(false), zce(0), defined(false)
{
}
void
-IcePHP::ClassInfo::define(const string& n, Ice::Int compact, bool isAbs, bool pres, zval* b, zval* i, zval* m)
+IcePHP::ClassInfo::define(const string& n, Ice::Int compact, bool pres, bool intf, zval* b, zval* m)
{
const_cast<string&>(name) = n;
const_cast<Ice::Int&>(compactId) = static_cast<Ice::Int>(compact);
- const_cast<bool&>(isAbstract) = isAbs;
const_cast<bool&>(preserve) = pres;
+ const_cast<bool&>(interface) = intf;
if(b)
{
@@ -2405,21 +2405,6 @@ IcePHP::ClassInfo::define(const string& n, Ice::Int compact, bool isAbs, bool pr
assert(base);
}
- if(i)
- {
- HashTable* interfacesArray = Z_ARRVAL_P(i);
- zval* interfaceType;
-
- ZEND_HASH_FOREACH_VAL(interfacesArray, interfaceType)
- {
- TypeInfoPtr t = Wrapper<TypeInfoPtr>::value(interfaceType);
- ClassInfoPtr c = ClassInfoPtr::dynamicCast(t);
- assert(c);
- const_cast<ClassInfoList&>(interfaces).push_back(c);
- }
- ZEND_HASH_FOREACH_END();
- }
-
if(m)
{
convertDataMembers(m, const_cast<DataMemberList&>(members), const_cast<DataMemberList&>(optionalMembers),
@@ -2427,8 +2412,13 @@ IcePHP::ClassInfo::define(const string& n, Ice::Int compact, bool isAbs, bool pr
}
const_cast<bool&>(defined) = true;
- const_cast<zend_class_entry*&>(zce) = nameToClass(name);
- assert(zce || id == "::Ice::LocalObject"); // LocalObject does not have a native PHP equivalent.
+#ifdef ICEPHP_USE_NAMESPACES
+ const string valueClass = "Ice\\Value";
+#else
+ const string valueClass = "Ice_Value";
+#endif
+ const_cast<zend_class_entry*&>(zce) = nameToClass(interface ? valueClass : name);
+ assert(zce || id == "::Ice::LocalObject" || interface); // LocalObject and interfaces does not have a native PHP equivalent.
}
string
@@ -2586,7 +2576,6 @@ void
IcePHP::ClassInfo::destroy()
{
const_cast<ClassInfoPtr&>(base) = 0;
- const_cast<ClassInfoList&>(interfaces).clear();
if(!members.empty())
{
DataMemberList ml = members;
@@ -2660,49 +2649,7 @@ IcePHP::ClassInfo::isA(const string& typeId) const
return true;
}
- if(base && base->isA(typeId))
- {
- return true;
- }
-
- for(ClassInfoList::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
- {
- if((*p)->isA(typeId))
- {
- return true;
- }
- }
-
- return false;
-}
-
-void
-IcePHP::ClassInfo::addOperation(const string& name, const OperationPtr& op)
-{
- operations.insert(OperationMap::value_type(Slice::PHP::fixIdent(name), op));
-}
-
-IcePHP::OperationPtr
-IcePHP::ClassInfo::getOperation(const string& name) const
-{
- OperationPtr op;
- OperationMap::const_iterator p = operations.find(name);
- if(p != operations.end())
- {
- op = p->second;
- }
- if(!op && base)
- {
- op = base->getOperation(name);
- }
- if(!op && !interfaces.empty())
- {
- for(ClassInfoList::const_iterator q = interfaces.begin(); q != interfaces.end() && !op; ++q)
- {
- op = (*q)->getOperation(name);
- }
- }
- return op;
+ return base && base->isA(typeId);
}
//
@@ -2714,9 +2661,30 @@ IcePHP::ProxyInfo::ProxyInfo(const string& ident) :
}
void
-IcePHP::ProxyInfo::define(const ClassInfoPtr& c)
+IcePHP::ProxyInfo::define(zval* b, zval* i)
{
- const_cast<ClassInfoPtr&>(cls) = c;
+ if(b)
+ {
+ TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(b);
+ const_cast<ProxyInfoPtr&>(base) = ProxyInfoPtr::dynamicCast(p);
+ assert(base);
+ }
+
+ if(i)
+ {
+ HashTable* interfacesArray = Z_ARRVAL_P(i);
+ zval* interfaceType;
+
+ ZEND_HASH_FOREACH_VAL(interfacesArray, interfaceType)
+ {
+ TypeInfoPtr t = Wrapper<TypeInfoPtr>::value(interfaceType);
+ ProxyInfoPtr c = ProxyInfoPtr::dynamicCast(t);
+ assert(c);
+ const_cast<ProxyInfoList&>(interfaces).push_back(c);
+ }
+ ZEND_HASH_FOREACH_END();
+ }
+
const_cast<bool&>(defined) = true;
}
@@ -2780,7 +2748,7 @@ IcePHP::ProxyInfo::marshal(zval* zv, Ice::OutputStream* os, ObjectMap*, bool opt
{
assert(Z_TYPE_P(zv) == IS_OBJECT && Z_OBJCE_P(zv) == proxyClassEntry); // validate() should have caught this.
Ice::ObjectPrx proxy;
- ClassInfoPtr info;
+ ProxyInfoPtr info;
if(!fetchProxy(zv, proxy, info))
{
throw AbortMarshaling();
@@ -2821,13 +2789,13 @@ IcePHP::ProxyInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& c
return;
}
- if(!cls->defined)
+ if(!defined)
{
- runtimeError("class or interface %s is declared but not defined", id.c_str());
+ runtimeError("proxy %s is declared but not defined" TSRMLS_CC, id.c_str());
throw AbortMarshaling();
}
- if(!createProxy(&zv, proxy, cls, comm))
+ if(!createProxy(&zv, proxy, this, comm))
{
throw AbortMarshaling();
}
@@ -2850,8 +2818,8 @@ IcePHP::ProxyInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHist
else
{
Ice::ObjectPrx proxy;
- ClassInfoPtr cls;
- if(!fetchProxy(zv, proxy, cls))
+ ProxyInfoPtr info;
+ if(!fetchProxy(zv, proxy, info))
{
return;
}
@@ -2862,27 +2830,83 @@ IcePHP::ProxyInfo::print(zval* zv, IceUtilInternal::Output& out, PrintObjectHist
void
IcePHP::ProxyInfo::destroy()
{
- const_cast<ClassInfoPtr&>(cls) = 0;
+ const_cast<ProxyInfoPtr&>(base) = 0;
+ const_cast<ProxyInfoList&>(interfaces).clear();
+}
+
+bool
+IcePHP::ProxyInfo::isA(const string& typeId) const
+{
+ if(id == typeId)
+ {
+ return true;
+ }
+
+ if(base && base->isA(typeId))
+ {
+ return true;
+ }
+
+ for(ProxyInfoList::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
+ {
+ if((*p)->isA(typeId))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+IcePHP::ProxyInfo::addOperation(const string& name, const OperationPtr& op)
+{
+ operations.insert(OperationMap::value_type(Slice::PHP::fixIdent(name), op));
+}
+
+IcePHP::OperationPtr
+IcePHP::ProxyInfo::getOperation(const string& name) const
+{
+ OperationPtr op;
+ OperationMap::const_iterator p = operations.find(name);
+ if(p != operations.end())
+ {
+ op = p->second;
+ }
+ if(!op && base)
+ {
+ op = base->getOperation(name);
+ }
+ if(!op && !interfaces.empty())
+ {
+ for(ProxyInfoList::const_iterator q = interfaces.begin(); q != interfaces.end() && !op; ++q)
+ {
+ op = (*q)->getOperation(name);
+ }
+ }
+ return op;
}
//
// ObjectWriter implementation.
//
IcePHP::ObjectWriter::ObjectWriter(zval* object, ObjectMap* objectMap, const ClassInfoPtr& formal) :
- _map(objectMap)
+ _map(objectMap), _formal(formal)
{
// Copy zval and increase ref count
ZVAL_COPY(&_object, object);
-
- //
- // We need to determine the most-derived Slice type supported by this object.
- // This is typically a Slice class, but it can also be an interface.
- //
- // The caller may have provided a ClassInfo representing the formal type, in
- // which case we ensure that the actual type is compatible with the formal type.
- //
- _info = getClassInfoByClass(Z_OBJCE_P(object), formal ? const_cast<zend_class_entry*>(formal->zce) : 0);
- assert(_info);
+ if(!_formal || !_formal->interface)
+ {
+ //
+ // For non interface types we need to determine the most-derived Slice type supported by
+ // this object. This is typically a Slice class, but it can also be an interface.
+ //
+ // The caller may have provided a ClassInfo representing the formal type, in
+ // which case we ensure that the actual type is compatible with the formal type.
+ //
+ _info = getClassInfoByClass(Z_OBJCE_P(object), formal ? const_cast<zend_class_entry*>(formal->zce) : 0);
+ assert(_info);
+ }
}
IcePHP::ObjectWriter::~ObjectWriter()
@@ -2908,7 +2932,7 @@ IcePHP::ObjectWriter::_iceWrite(Ice::OutputStream* os) const
{
Ice::SlicedDataPtr slicedData;
- if(_info->preserve)
+ if(_info && _info->preserve)
{
//
// Retrieve the SlicedData object that we stored as a hidden member of the PHP object.
@@ -2917,25 +2941,66 @@ IcePHP::ObjectWriter::_iceWrite(Ice::OutputStream* os) const
}
os->startValue(slicedData);
+
+ if(_formal && _formal->interface)
+ {
+ //
+ // For an interface by value we just marshal the Ice type id
+ // of the object in its own slice.
+ //
+ zval ret;
+ ZVAL_UNDEF(&ret);
+
+ zend_try
+ {
+ assert(Z_TYPE(_object) == IS_OBJECT);
+ zend_call_method(const_cast<zval*>(&_object), 0, 0, const_cast<char*>("ice_id"), sizeof("ice_id") - 1, &ret, 0, 0, 0);
+ }
+ zend_catch
+ {
+ // ret;
+ }
+ zend_end_try();
+
+ //
+ // Bail out if an exception has already been thrown.
+ //
+ if(Z_ISUNDEF(ret) || EG(exception))
+ {
+ throw AbortMarshaling();
+ }
- if(_info->id != "::Ice::UnknownSlicedObject")
+ AutoDestroy destroy(&ret);
+
+ if(Z_TYPE(ret) != IS_STRING)
+ {
+ throw AbortMarshaling();
+ }
+
+ string id(Z_STRVAL(ret), Z_STRLEN(ret));
+ os->startSlice(id, -1, true);
+ os->endSlice();
+ }
+ else
{
- ClassInfoPtr info = _info;
- while(info && info->id != Ice::Object::ice_staticId())
+ if(_info->id != "::Ice::UnknownSlicedValue")
{
- assert(info->base); // All classes have the Ice::Object base type.
- const bool lastSlice = info->base->id == Ice::Object::ice_staticId();
- os->startSlice(info->id, info->compactId, lastSlice);
+ ClassInfoPtr info = _info;
+ while(info && info->id != Ice::Object::ice_staticId())
+ {
+ assert(info->base); // All classes have the Ice::Object base type.
+ const bool lastSlice = info->base->id == Ice::Object::ice_staticId();
+ os->startSlice(info->id, info->compactId, lastSlice);
- writeMembers(os, info->members);
- writeMembers(os, info->optionalMembers); // The optional members have already been sorted by tag.
+ writeMembers(os, info->members);
+ writeMembers(os, info->optionalMembers); // The optional members have already been sorted by tag.
- os->endSlice();
+ os->endSlice();
- info = info->base;
+ info = info->base;
+ }
}
}
-
os->endValue();
}
@@ -3022,8 +3087,7 @@ void
IcePHP::ObjectReader::_iceRead(Ice::InputStream* is)
{
is->startValue();
-
- const bool unknown = _info->id == "::Ice::UnknownSlicedObject";
+ const bool unknown = _info->id == "::Ice::UnknownSlicedValue";
//
// Unmarshal the slices of a user-defined class.
@@ -3144,7 +3208,7 @@ IcePHP::ReadObjectCallback::invoke(const Ice::ObjectPtr& p)
// Verify that the unmarshaled object is compatible with the formal type.
//
zval* obj = reader->getObject();
- if(!reader->getInfo()->isA(_info->id))
+ if(!_info->interface && !reader->getInfo()->isA(_info->id))
{
Ice::UnexpectedObjectException ex(__FILE__, __LINE__);
ex.reason = "unmarshaled object is not an instance of " + _info->id;
@@ -3573,25 +3637,23 @@ ZEND_FUNCTION(IcePHP_declareProxy)
ZEND_FUNCTION(IcePHP_defineProxy)
{
- zval* cls;
+ char* id;
+ size_t idLen;
+ zval* base;
+ zval* interfaces;
- if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("o"), &cls) == FAILURE)
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("so!a!"), &id, &idLen, &base, &interfaces) == FAILURE)
{
return;
}
- TypeInfoPtr p = Wrapper<TypeInfoPtr>::value(cls);
- ClassInfoPtr c = ClassInfoPtr::dynamicCast(p);
- assert(c);
-
- ProxyInfoPtr type = getProxyInfo(c->id);
+ ProxyInfoPtr type = getProxyInfo(id);
if(!type)
{
- type = new ProxyInfo(c->id);
+ type = new ProxyInfo(id);
addProxyInfo(type);
}
-
- type->define(c);
+ type->define(base, interfaces);
if(!createTypeInfo(return_value, type))
{
@@ -3629,14 +3691,13 @@ ZEND_FUNCTION(IcePHP_defineClass)
char* name;
size_t nameLen;
long compactId;
- zend_bool isAbstract;
zend_bool preserve;
+ zend_bool interface;
zval* base;
- zval* interfaces;
zval* members;
- if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("sslbbo!a!a!"), &id, &idLen, &name, &nameLen,
- &compactId, &isAbstract, &preserve, &base, &interfaces, &members) == FAILURE)
+ if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("sslbbo!a!"), &id, &idLen, &name, &nameLen,
+ &compactId, &preserve, &interface, &base, &members) == FAILURE)
{
return;
}
@@ -3648,17 +3709,23 @@ ZEND_FUNCTION(IcePHP_defineClass)
addClassInfoById(type);
}
- type->define(name, static_cast<Ice::Int>(compactId), isAbstract ? true : false, preserve ? true : false, base,
- interfaces, members);
- addClassInfoByName(type);
+ type->define(name, static_cast<Ice::Int>(compactId), preserve ? true : false, interface ? true : false, base, members);
+
+ if(!interface)
+ {
+ addClassInfoByName(type);
+ }
- CompactIdMap* m = reinterpret_cast<CompactIdMap*>(ICE_G(compactIdToClassInfoMap));
- if(!m)
+ if(type->compactId != -1)
{
- m = new CompactIdMap;
- ICE_G(compactIdToClassInfoMap) = m;
+ CompactIdMap* m = reinterpret_cast<CompactIdMap*>(ICE_G(compactIdToClassInfoMap));
+ if(!m)
+ {
+ m = new CompactIdMap;
+ ICE_G(compactIdToClassInfoMap) = m;
+ }
+ m->insert(CompactIdMap::value_type(type->compactId, type));
}
- m->insert(CompactIdMap::value_type(type->compactId, type));
if(!createTypeInfo(return_value, type))
{
diff --git a/php/src/php7/Types.h b/php/src/php7/Types.h
index 111c5f77c76..971f7837cf6 100644
--- a/php/src/php7/Types.h
+++ b/php/src/php7/Types.h
@@ -414,7 +414,7 @@ public:
ClassInfo(const std::string&);
- void define(const std::string&, Ice::Int, bool, bool, zval*, zval*, zval*);
+ void define(const std::string&, Ice::Int, bool, bool, zval*, zval*);
virtual std::string getId() const;
@@ -438,35 +438,33 @@ public:
bool isA(const std::string&) const;
- void addOperation(const std::string&, const OperationPtr&);
- OperationPtr getOperation(const std::string&) const;
-
const std::string id;
const std::string name; // PHP class name
const Ice::Int compactId;
- const bool isAbstract;
const bool preserve;
+ const bool interface;
const ClassInfoPtr base;
- const ClassInfoList interfaces;
const DataMemberList members;
const DataMemberList optionalMembers;
const zend_class_entry* zce;
bool defined;
-
- typedef std::map<std::string, OperationPtr> OperationMap;
- OperationMap operations;
};
//
// Proxy information.
//
+
+class ProxyInfo;
+typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr;
+typedef std::vector<ProxyInfoPtr> ProxyInfoList;
+
class ProxyInfo : public TypeInfo
{
public:
ProxyInfo(const std::string&);
- void define(const ClassInfoPtr&);
+ void define(zval*, zval*);
virtual std::string getId() const;
@@ -483,12 +481,18 @@ public:
virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*);
virtual void destroy();
+ bool isA(const std::string&) const;
+
+ void addOperation(const std::string&, const OperationPtr&);
+ OperationPtr getOperation(const std::string&) const;
const std::string id;
- const ClassInfoPtr cls;
+ const ProxyInfoPtr base;
+ const ProxyInfoList interfaces;
bool defined;
+ typedef std::map<std::string, OperationPtr> OperationMap;
+ OperationMap operations;
};
-typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr;
//
// Exception information.
@@ -516,6 +520,7 @@ public:
ClassInfoPtr getClassInfoById(const std::string&);
ClassInfoPtr getClassInfoByName(const std::string&);
+ProxyInfoPtr getProxyInfo(const std::string&);
ExceptionInfoPtr getExceptionInfo(const std::string&);
bool isUnset(zval*);
@@ -547,6 +552,7 @@ private:
zval _object;
ObjectMap* _map;
ClassInfoPtr _info;
+ ClassInfoPtr _formal;
};
//
diff --git a/php/test/Ice/objects/Client.php b/php/test/Ice/objects/Client.php
index b7c0b2dc4a1..05e7a92be73 100644
--- a/php/test/Ice/objects/Client.php
+++ b/php/test/Ice/objects/Client.php
@@ -30,10 +30,9 @@ if($NS)
class Test_D1 extends Test\D1 {}
abstract class Test_E extends Test\E {}
abstract class Test_F extends Test\F {}
- interface Test_I extends Test\I {}
- interface Test_J extends Test\J {}
class Test_H extends Test\H {}
- class Ice_ObjectImpl extends Ice\ObjectImpl {}
+ class Ice_Value extends Ice\Value {}
+ class Ice_InterfaceByValue extends Ice\InterfaceByValue {}
interface Ice_ObjectFactory extends Ice\ObjectFactory {}
interface Ice_ValueFactory extends Ice\ValueFactory {}
EOT;
@@ -107,12 +106,20 @@ class FI extends Test_F
}
}
-class II extends Ice_ObjectImpl implements Test_I
+class II extends Ice_InterfaceByValue
{
+ public function __construct()
+ {
+ parent::__construct("::Test::I");
+ }
}
-class JI extends Ice_ObjectImpl implements Test_J
+class JI extends Ice_InterfaceByValue
{
+ public function __construct()
+ {
+ parent::__construct("::Test::J");
+ }
}
class HI extends Test_H
@@ -349,9 +356,9 @@ function allTests($communicator)
$i = $initial->getI();
test($i != null);
$j = $initial->getJ();
- test($j != null and $j instanceof Test_J);
+ test($j != null and $j instanceof JI);
$h = $initial->getH();
- test($h != null and $h instanceof Test_H);
+ test($h != null and $h instanceof HI);
echo "ok\n";
echo "getting D1... ";
diff --git a/php/test/Ice/proxy/Client.php b/php/test/Ice/proxy/Client.php
index 54ccb759d07..4b4681cdee3 100644
--- a/php/test/Ice/proxy/Client.php
+++ b/php/test/Ice/proxy/Client.php
@@ -36,6 +36,7 @@ function allTests($communicator)
global $Ice_Encoding_1_0;
global $Ice_Encoding_1_1;
+ $identity = $NS ? "Ice\\Identity" : "Ice_Identity";
$random = $NS ? constant("Ice\\EndpointSelectionType::Random") : constant("Ice_EndpointSelectionType::Random");
$ordered = $NS ? constant("Ice\\EndpointSelectionType::Ordered") : constant("Ice_EndpointSelectionType::Ordered");
$encodingVersion = $NS ? "Ice\\EncodingVersion" : "Ice_EncodingVersion";
@@ -455,7 +456,7 @@ function allTests($communicator)
//
// Verify that ToStringMode is passed correctly
//
- $ident = new Ice_Identity("test", "\x7F\xE2\x82\xAC");
+ $ident = eval("return new " . $identity . "('test', '\x7F\xE2\x82\xAC');");
$idStr = $identityToString($ident, $modeUnicode);
test($idStr == "\\u007f\xE2\x82\xAC/test");
diff --git a/php/test/Ice/slicing/objects/Client.php b/php/test/Ice/slicing/objects/Client.php
index ba00029a2d6..44f35507ffc 100644
--- a/php/test/Ice/slicing/objects/Client.php
+++ b/php/test/Ice/slicing/objects/Client.php
@@ -110,7 +110,7 @@ function allTests($communicator)
echo "unknown with Object as Object... ";
flush();
{
- $usocls = $NS ? "Ice\\UnknownSlicedObject" : "Ice_UnknownSlicedObject";
+ $usocls = $NS ? "Ice\\UnknownSlicedValue" : "Ice_UnknownSlicedValue";
try
{
$o = $test->SUnknownAsObject();
diff --git a/slice/Ice/Communicator.ice b/slice/Ice/Communicator.ice
index fea415508a7..4b4356627cb 100644
--- a/slice/Ice/Communicator.ice
+++ b/slice/Ice/Communicator.ice
@@ -54,7 +54,7 @@ module Ice
* @see ValueFactory
*
**/
-["clr:implements:_System.IDisposable"]
+["clr:implements:_System.IDisposable", "php:internal"]
local interface Communicator
{
/**
diff --git a/slice/Ice/Connection.ice b/slice/Ice/Connection.ice
index e5f04ed95d6..e87f8527958 100644
--- a/slice/Ice/Connection.ice
+++ b/slice/Ice/Connection.ice
@@ -27,6 +27,7 @@ module Ice
*
* Base class providing access to the connection details. *
**/
+["php:internal"]
local class ConnectionInfo
{
/**
@@ -135,6 +136,7 @@ local struct ACM
* The user-level interface to a connection.
*
**/
+["php:internal"]
local interface Connection
{
/**
@@ -322,6 +324,7 @@ local interface Connection
* Provides access to the connection details of an IP connection
*
**/
+["php:internal"]
local class IPConnectionInfo extends ConnectionInfo
{
/** The local address. */
@@ -342,6 +345,7 @@ local class IPConnectionInfo extends ConnectionInfo
* Provides access to the connection details of a TCP connection
*
**/
+["php:internal"]
local class TCPConnectionInfo extends IPConnectionInfo
{
/**
@@ -364,6 +368,7 @@ local class TCPConnectionInfo extends IPConnectionInfo
* Provides access to the connection details of a UDP connection
*
**/
+["php:internal"]
local class UDPConnectionInfo extends IPConnectionInfo
{
/**
@@ -402,6 +407,7 @@ dictionary<string, string> HeaderDict;
* Provides access to the connection details of a WebSocket connection
*
**/
+["php:internal"]
local class WSConnectionInfo extends ConnectionInfo
{
/** The headers from the HTTP upgrade request. */
diff --git a/slice/Ice/Endpoint.ice b/slice/Ice/Endpoint.ice
index 9dbd62826c3..09c69ddf9fd 100644
--- a/slice/Ice/Endpoint.ice
+++ b/slice/Ice/Endpoint.ice
@@ -91,6 +91,7 @@ const short iAPSEndpointType = 9;
* Base class providing access to the endpoint details.
*
**/
+["php:internal"]
local class EndpointInfo
{
/**
@@ -150,7 +151,7 @@ local class EndpointInfo
* The user-level interface to an endpoint.
*
**/
-["cpp:comparable"]
+["cpp:comparable", "php:internal"]
local interface Endpoint
{
/**
@@ -179,6 +180,7 @@ local interface Endpoint
* @see Endpoint
*
**/
+["php:internal"]
local class IPEndpointInfo extends EndpointInfo
{
/**
@@ -210,6 +212,7 @@ local class IPEndpointInfo extends EndpointInfo
* @see Endpoint
*
**/
+["php:internal"]
local class TCPEndpointInfo extends IPEndpointInfo
{
};
@@ -221,6 +224,7 @@ local class TCPEndpointInfo extends IPEndpointInfo
* @see Endpoint
*
**/
+["php:internal"]
local class UDPEndpointInfo extends IPEndpointInfo
{
/**
@@ -243,6 +247,7 @@ local class UDPEndpointInfo extends IPEndpointInfo
* Provides access to a WebSocket endpoint information.
*
**/
+["php:internal"]
local class WSEndpointInfo extends EndpointInfo
{
/**
@@ -260,6 +265,7 @@ local class WSEndpointInfo extends EndpointInfo
* @see Endpoint
*
**/
+["php:internal"]
local class OpaqueEndpointInfo extends EndpointInfo
{
/**
diff --git a/slice/Ice/ObjectFactory.ice b/slice/Ice/ObjectFactory.ice
index dd456d2d84a..ba911f4c9bd 100644
--- a/slice/Ice/ObjectFactory.ice
+++ b/slice/Ice/ObjectFactory.ice
@@ -27,7 +27,7 @@ module Ice
*
**/
-["deprecate:ObjectFactory has been deprecated, use ValueFactory instead."]
+["deprecate:ObjectFactory has been deprecated, use ValueFactory instead.", "php:internal"]
local interface ObjectFactory
{
/**
diff --git a/slice/Ice/Properties.ice b/slice/Ice/Properties.ice
index 494db29fdc5..5969ad6d496 100644
--- a/slice/Ice/Properties.ice
+++ b/slice/Ice/Properties.ice
@@ -29,6 +29,7 @@ module Ice
* <em>application-name</em>\[.<em>category</em>\[.<em>sub-category</em>]].<em>name</em>.
*
**/
+["php:internal"]
local interface Properties
{
/**
diff --git a/slice/Ice/ValueFactory.ice b/slice/Ice/ValueFactory.ice
index 1cf0c8c5ab5..3f34124de13 100644
--- a/slice/Ice/ValueFactory.ice
+++ b/slice/Ice/ValueFactory.ice
@@ -28,7 +28,7 @@ module Ice
* with the communicator.
*
**/
-["delegate"]
+["delegate", "php:internal"]
local interface ValueFactory
{
/**
@@ -59,6 +59,7 @@ local interface ValueFactory
* @see ValueFactory
*
**/
+["php:internal"]
local interface ValueFactoryManager
{
/**