Improve arginfo generation
Fixes some failing examples and testcases.
This commit is contained in:
parent
f77113ea71
commit
4aff93942a
1 changed files with 38 additions and 16 deletions
|
|
@ -771,44 +771,49 @@ public:
|
||||||
/* Just need to append function names to function table to register with PHP. */
|
/* Just need to append function names to function table to register with PHP. */
|
||||||
void create_command(String *cname, String *fname, Node *n, bool overload, String *modes = NULL) {
|
void create_command(String *cname, String *fname, Node *n, bool overload, String *modes = NULL) {
|
||||||
// This is for the single main zend_function_entry record
|
// This is for the single main zend_function_entry record
|
||||||
|
bool has_this = false;
|
||||||
if (cname && Cmp(Getattr(n, "storage"), "friend") != 0) {
|
if (cname && Cmp(Getattr(n, "storage"), "friend") != 0) {
|
||||||
Printf(f_h, "PHP_METHOD(%s,%s);\n", cname, fname);
|
Printf(f_h, "PHP_METHOD(%s,%s);\n", cname, fname);
|
||||||
|
has_this = (wrapperType != staticmemberfn) &&
|
||||||
|
(wrapperType != staticmembervar) &&
|
||||||
|
(Cmp(fname,"__construct") != 0);
|
||||||
} else {
|
} else {
|
||||||
if (overload)
|
if (overload) {
|
||||||
Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", fname);
|
Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", fname);
|
||||||
else
|
} else {
|
||||||
Printf(f_h, "PHP_FUNCTION(%s);\n", fname);
|
Printf(f_h, "PHP_FUNCTION(%s);\n", fname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// We want to only emit each different arginfo once, as that reduces the
|
// We want to only emit each different arginfo once, as that reduces the
|
||||||
// size of both the generated source code and the compiled extension
|
// size of both the generated source code and the compiled extension
|
||||||
// module. The parameters at this level are just named arg1, arg2, etc
|
// module. The parameters at this level are just named arg1, arg2, etc
|
||||||
// so we generate an arginfo name with the number of parameters and a
|
// so we generate an arginfo name with the number of parameters and a
|
||||||
// bitmap value saying which (if any) are passed by reference.
|
// bitmap value saying which (if any) are passed by reference.
|
||||||
bool constructor = false;
|
|
||||||
if (Cmp(fname,"__construct") == 0) {
|
|
||||||
constructor = true;
|
|
||||||
}
|
|
||||||
ParmList *l = Getattr(n, "parms");
|
ParmList *l = Getattr(n, "parms");
|
||||||
int Iterator = 0;
|
|
||||||
unsigned long bitmap = 0, bit = 1;
|
unsigned long bitmap = 0, bit = 1;
|
||||||
int n_params = 0;
|
|
||||||
bool overflowed = false;
|
bool overflowed = false;
|
||||||
|
bool skip_this = has_this;
|
||||||
for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
|
for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
|
||||||
/* Ignored parameters */
|
if (skip_this) {
|
||||||
if ((overload || (!constructor && class_name)) && (Iterator == 0)) {
|
skip_this = false;
|
||||||
Iterator++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||||
|
/* Ignored parameter */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++n_params;
|
|
||||||
if (GetFlag(p, "tmap:in:byref")) {
|
if (GetFlag(p, "tmap:in:byref")) {
|
||||||
bitmap |= bit;
|
bitmap |= bit;
|
||||||
if (bit == 0) overflowed = true;
|
if (bit == 0) overflowed = true;
|
||||||
}
|
}
|
||||||
bit <<= 1;
|
bit <<= 1;
|
||||||
}
|
}
|
||||||
|
int num_arguments = emit_num_arguments(l);
|
||||||
|
int num_required = emit_num_required(l);
|
||||||
|
if (has_this) {
|
||||||
|
--num_arguments;
|
||||||
|
--num_required;
|
||||||
|
}
|
||||||
String * arginfo_code;
|
String * arginfo_code;
|
||||||
if (overflowed) {
|
if (overflowed) {
|
||||||
// We overflowed the bitmap so just generate a unique name - this only
|
// We overflowed the bitmap so just generate a unique name - this only
|
||||||
|
|
@ -819,16 +824,33 @@ public:
|
||||||
arginfo_code = NewStringf("z%d", ++overflowed_counter);
|
arginfo_code = NewStringf("z%d", ++overflowed_counter);
|
||||||
} else if (bitmap == 0) {
|
} else if (bitmap == 0) {
|
||||||
// No parameters passed by reference.
|
// No parameters passed by reference.
|
||||||
arginfo_code = NewStringf("%d", n_params);
|
if (num_required == num_arguments) {
|
||||||
|
arginfo_code = NewStringf("%d", num_arguments);
|
||||||
|
} else {
|
||||||
|
arginfo_code = NewStringf("%d_%d", num_required, num_arguments);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
arginfo_code = NewStringf("%d_%lx", n_params, bitmap);
|
if (num_required == num_arguments) {
|
||||||
|
arginfo_code = NewStringf("%d_r%lx", num_arguments, bitmap);
|
||||||
|
} else {
|
||||||
|
arginfo_code = NewStringf("%d_%d_r%lx", num_required, num_arguments, bitmap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetFlag(arginfo_used, arginfo_code)) {
|
if (!GetFlag(arginfo_used, arginfo_code)) {
|
||||||
// Not had this one before so emit it.
|
// Not had this one before so emit it.
|
||||||
SetFlag(arginfo_used, arginfo_code);
|
SetFlag(arginfo_used, arginfo_code);
|
||||||
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, %d)\n", arginfo_code, n_params);
|
Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, %d)\n", arginfo_code, num_required);
|
||||||
|
bool skip_this = has_this;
|
||||||
for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
|
for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
|
||||||
|
if (skip_this) {
|
||||||
|
skip_this = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||||
|
/* Ignored parameter */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Printf(s_arginfo, " ZEND_ARG_INFO(%d,%s)\n", GetFlag(p, "tmap:in:byref"), Getattr(p, "lname"));
|
Printf(s_arginfo, " ZEND_ARG_INFO(%d,%s)\n", GetFlag(p, "tmap:in:byref"), Getattr(p, "lname"));
|
||||||
}
|
}
|
||||||
Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
|
Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue