[PHP] Fix director code to work when PHP is built with ZTS enabled,

which is the standard configuration on Microsoft Windows.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12749 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Olly Betts 2011-06-23 16:04:42 +00:00
commit 688ea24560
3 changed files with 61 additions and 18 deletions

View file

@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress) Version 2.0.5 (in progress)
=========================== ===========================
2011-06-23: olly
[PHP] Fix director code to work when PHP is built with ZTS enabled,
which is the standard configuration on Microsoft Windows.
2011-06-21: mutandiz 2011-06-21: mutandiz
[allegrocl] [allegrocl]
- various small tweaks and bug fixes. - various small tweaks and bug fixes.

View file

@ -102,11 +102,17 @@ namespace Swig {
zval *swig_self; zval *swig_self;
typedef std::map<void*, GCItem_var> swig_ownership_map; typedef std::map<void*, GCItem_var> swig_ownership_map;
mutable swig_ownership_map swig_owner; mutable swig_ownership_map swig_owner;
#ifdef ZTS
// Store the ZTS context so it's available when C++ calls back to PHP.
void *** swig_zts_ctx;
#endif
public: public:
Director(zval* self) : swig_self(self) { Director(zval* self TSRMLS_DC) : swig_self(self) {
TSRMLS_SET_CTX(swig_zts_ctx);
} }
bool swig_is_overridden_method(char *cname, char *lc_fname) { bool swig_is_overridden_method(char *cname, char *lc_fname) {
TSRMLS_FETCH_FROM_CTX(swig_zts_ctx);
zend_class_entry **ce; zend_class_entry **ce;
zend_function *mptr; zend_function *mptr;
int name_len = strlen(lc_fname); int name_len = strlen(lc_fname);
@ -135,7 +141,7 @@ namespace Swig {
protected: protected:
std::string swig_msg; std::string swig_msg;
public: public:
DirectorException(int code, const char *hdr, const char* msg) DirectorException(int code, const char *hdr, const char* msg TSRMLS_DC)
: swig_msg(hdr) : swig_msg(hdr)
{ {
if (strlen(msg)) { if (strlen(msg)) {
@ -146,9 +152,9 @@ namespace Swig {
SWIG_ErrorMsg() = swig_msg.c_str(); SWIG_ErrorMsg() = swig_msg.c_str();
} }
static void raise(int code, const char *hdr, const char* msg) static void raise(int code, const char *hdr, const char* msg TSRMLS_DC)
{ {
throw DirectorException(code, hdr, msg); throw DirectorException(code, hdr, msg TSRMLS_CC);
} }
}; };
@ -156,32 +162,36 @@ namespace Swig {
class DirectorPureVirtualException : public Swig::DirectorException class DirectorPureVirtualException : public Swig::DirectorException
{ {
public: public:
DirectorPureVirtualException(const char* msg) DirectorPureVirtualException(const char* msg TSRMLS_DC)
: DirectorException(E_ERROR, "SWIG director pure virtual method called", msg) : DirectorException(E_ERROR, "SWIG director pure virtual method called", msg TSRMLS_CC)
{ {
} }
static void raise(const char *msg) static void raise(const char *msg TSRMLS_DC)
{ {
throw DirectorPureVirtualException(msg); throw DirectorPureVirtualException(msg TSRMLS_CC);
} }
}; };
/* any php exception that occurs during a director method call */ /* any php exception that occurs during a director method call */
class DirectorMethodException : public Swig::DirectorException class DirectorMethodException : public Swig::DirectorException
{ {
public: public:
DirectorMethodException(const char* msg = "") DirectorMethodException(const char* msg TSRMLS_DC)
: DirectorException(E_ERROR, "SWIG director method error", msg) : DirectorException(E_ERROR, "SWIG director method error", msg TSRMLS_CC)
{ {
} }
static void raise(const char *msg) static void raise(const char *msg TSRMLS_DC)
{ {
throw DirectorMethodException(msg); throw DirectorMethodException(msg TSRMLS_CC);
} }
}; };
} }
// DirectorMethodException() is documented to be callable with no parameters
// so use a macro to insert TSRMLS_CC so any ZTS context gets passed.
#define DirectorMethodException() DirectorMethodException("" TSRMLS_CC)
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif

View file

@ -182,6 +182,23 @@ static void SwigPHP_emit_resource_registrations() {
} }
class PHP : public Language { class PHP : public Language {
String *emit_action(Node *n) {
// Adjust wrap:action to add TSRMLS_CC.
String * action = Getattr(n, "wrap:action");
if (action) {
char * p = Strstr(action, "Swig::DirectorPureVirtualException::raise(\"");
if (p) {
p += strlen("Swig::DirectorPureVirtualException::raise(\"");
p = strchr(p, '"');
if (p) {
++p;
Insert(action, p - Char(action), " TSRMLS_CC");
}
}
}
return ::emit_action(n);
}
public: public:
PHP() { PHP() {
director_language = 1; director_language = 1;
@ -2237,8 +2254,8 @@ done:
if (i) { if (i) {
Insert(args, 0, ", "); Insert(args, 0, ", ");
} }
Printf(director_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s);\n}\n", ctype, sname, args); Printf(director_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s TSRMLS_CC);\n}\n", ctype, sname, args);
Printf(director_prot_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s);\n}\n", ctype, sname, args); Printf(director_prot_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s TSRMLS_CC);\n}\n", ctype, sname, args);
Delete(args); Delete(args);
wrapperType = directorconstructor; wrapperType = directorconstructor;
@ -2359,8 +2376,13 @@ done:
String *call; String *call;
String *basetype = Getattr(parent, "classtype"); String *basetype = Getattr(parent, "classtype");
String *target = Swig_method_decl(0, decl, classname, parms, 0, 0); String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
if (((const char *)Char(target))[Len(target) - 2] == '(') {
Insert(target, Len(target) - 1, "TSRMLS_D");
} else {
Insert(target, Len(target) - 1, " TSRMLS_DC");
}
call = Swig_csuperclass_call(0, basetype, superparms); call = Swig_csuperclass_call(0, basetype, superparms);
Printf(w->def, "%s::%s: %s, Swig::Director(self) {", classname, target, call); Printf(w->def, "%s::%s: %s, Swig::Director(self TSRMLS_CC) {", classname, target, call);
Append(w->def, "}"); Append(w->def, "}");
Delete(target); Delete(target);
Wrapper_print(w, f_directors); Wrapper_print(w, f_directors);
@ -2371,6 +2393,11 @@ done:
/* constructor header */ /* constructor header */
{ {
String *target = Swig_method_decl(0, decl, classname, parms, 0, 1); String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
if (((const char *)Char(target))[Len(target) - 2] == '(') {
Insert(target, Len(target) - 1, "TSRMLS_D");
} else {
Insert(target, Len(target) - 1, " TSRMLS_DC");
}
Printf(f_directors_h, " %s;\n", target); Printf(f_directors_h, " %s;\n", target);
Delete(target); Delete(target);
} }
@ -2474,6 +2501,8 @@ done:
Append(w->def, " {"); Append(w->def, " {");
Append(declaration, ";\n"); Append(declaration, ";\n");
Printf(w->code, "TSRMLS_FETCH_FROM_CTX(swig_zts_ctx);\n");
/* declare method return value /* declare method return value
* if the return value is a reference or const reference, a specialized typemap must * if the return value is a reference or const reference, a specialized typemap must
* handle it, including declaration of c_result ($result). * handle it, including declaration of c_result ($result).
@ -2494,7 +2523,7 @@ done:
Printf(w->code, "%s;\n", super_call); Printf(w->code, "%s;\n", super_call);
Delete(super_call); Delete(super_call);
} else { } else {
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\" TSRMLS_CC);\n", SwigType_namestr(c_classname),
SwigType_namestr(name)); SwigType_namestr(name));
} }
} else { } else {