cvs: ZendEngine2 / zend_API.c zend_compile.c zend_compile.h
| From: | Zeev Suraski | Date: | Sat, 29 Mar 2003 11:19:38 +0000 |
| Subject: | cvs: ZendEngine2 / zend_API.c zend_compile.c zend_compile.h | ||
| Groups: | php.zend-engine.cvs | ||
| Request: | Send a blank email to php-zend-engine-cvs+get-1076@lists.php.net to get a copy of this message | ||
zeev Sat Mar 29 06:19:38 2003 EDT
Modified files:
/ZendEngine2 zend_API.c zend_compile.c zend_compile.h
Log:
Initial support for enforcing prototype of abstract/interface method implementations
Index: ZendEngine2/zend_API.c
diff -u ZendEngine2/zend_API.c:1.161 ZendEngine2/zend_API.c:1.162
--- ZendEngine2/zend_API.c:1.161 Wed Mar 26 02:44:09 2003
+++ ZendEngine2/zend_API.c Sat Mar 29 06:19:37 2003
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_API.c,v 1.161 2003/03/26 07:44:09 sebastian Exp $ */
+/* $Id: zend_API.c,v 1.162 2003/03/29 11:19:37 zeev Exp $ */
#include "zend.h"
#include "zend_execute.h"
@@ -1166,6 +1166,7 @@
internal_function->scope = scope;
internal_function->fn_flags = ZEND_ACC_PUBLIC;
internal_function->ns = EG(active_namespace);
+ internal_function->prototype = NULL;
if (!internal_function->handler) {
zend_error(error_type, "Null function defined as active function");
zend_unregister_functions(functions, count, target_function_table TSRMLS_CC);
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.400 ZendEngine2/zend_compile.c:1.401
--- ZendEngine2/zend_compile.c:1.400 Wed Mar 26 12:06:08 2003
+++ ZendEngine2/zend_compile.c Sat Mar 29 06:19:37 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_compile.c,v 1.400 2003/03/26 17:06:08 iliaa Exp $ */
+/* $Id: zend_compile.c,v 1.401 2003/03/29 11:19:37 zeev Exp $ */
#include "zend_language_parser.h"
#include "zend.h"
@@ -1630,6 +1630,53 @@
}
+static zend_bool zend_do_perform_implementation_check(zend_function *fe)
+{
+ zend_op *op, *proto_op;
+
+ if (!fe->common.prototype) {
+ return 1;
+ }
+
+ if ((fe->common.arg_types && !fe->common.prototype->common.arg_types)
+ || (!fe->common.arg_types && fe->common.prototype->common.arg_types)) {
+ return 0;
+ }
+
+ if (fe->common.arg_types) {
+ if (fe->common.arg_types[0] != fe->common.prototype->common.arg_types[0]) {
+ return 0;
+ }
+ if (memcmp(fe->common.arg_types+1, fe->common.prototype->common.arg_types+1,
fe->common.arg_types[0]*sizeof(zend_uchar)) != 0) {
+ return 0;
+ }
+ }
+
+ if (fe->common.prototype->type == ZEND_INTERNAL_FUNCTION) {
+ return 1; /* nothing further we can do here */
+ }
+
+ op = fe->op_array.opcodes;
+ proto_op = fe->common.prototype->op_array.opcodes;
+
+ while (proto_op->opcode != ZEND_RAISE_ABSTRACT_ERROR) {
+ if (proto_op->opcode != op->opcode) {
+ return 0;
+ }
+ switch (proto_op->opcode) {
+ case ZEND_FETCH_CLASS:
+ if (zend_binary_zval_strcasecmp(&op->op2.u.constant,
&proto_op->op2.u.constant)!=0) {
+ return 0;
+ }
+ break;
+ }
+ proto_op++;
+ op++;
+ }
+ return 1;
+}
+
+
static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_function *parent,
zend_hash_key *hash_key, zend_class_entry *child_ce)
{
zend_uint child_flags;
@@ -1674,6 +1721,16 @@
&& ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) {
child->common.fn_flags |= ZEND_ACC_CHANGED;
}
+ }
+
+ if (parent_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_ABSTRACT)) {
+ child->common.prototype = parent;
+ } else if (parent->common.prototype) {
+ child->common.prototype = parent->common.prototype;
+ }
+
+ if (!zend_do_perform_implementation_check(child)) {
+ zend_error(E_COMPILE_ERROR, "Declaration of %s::%s() must be the same as %s::%s()",
ZEND_FN_SCOPE_NAME(child), child->common.function_name,
ZEND_FN_SCOPE_NAME(child->common.prototype),
child->common.prototype->common.function_name);
}
return 0;
Index: ZendEngine2/zend_compile.h
diff -u ZendEngine2/zend_compile.h:1.227 ZendEngine2/zend_compile.h:1.228
--- ZendEngine2/zend_compile.h:1.227 Wed Mar 26 02:44:09 2003
+++ ZendEngine2/zend_compile.h Sat Mar 29 06:19:38 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: zend_compile.h,v 1.227 2003/03/26 07:44:09 sebastian Exp $ */
+/* $Id: zend_compile.h,v 1.228 2003/03/29 11:19:38 zeev Exp $ */
#ifndef ZEND_COMPILE_H
#define ZEND_COMPILE_H
@@ -116,13 +116,15 @@
struct _zend_op_array {
- zend_uchar type; /* MUST be the first element of this struct! */
-
- zend_uchar *arg_types; /* MUST be the second element of this struct! */
- char *function_name; /* MUST be the third element of this struct! */
- zend_class_entry *scope; /* MUST be the fourth element of this struct! */
- zend_uint fn_flags; /* MUST be the fifth element of this struct! */
+ /* Common elements */
+ zend_uchar type;
+ zend_uchar *arg_types;
+ char *function_name;
+ zend_class_entry *scope;
+ zend_uint fn_flags;
zend_namespace *ns;
+ union _zend_function *prototype;
+ /* END of common elements */
zend_uint *refcount;
@@ -154,13 +156,15 @@
typedef struct _zend_internal_function {
- zend_uchar type; /* MUST be the first element of this struct! */
-
- zend_uchar *arg_types; /* MUST be the second element of this struct! */
- char *function_name; /* MUST be the third element of this struct! */
- zend_class_entry *scope; /* MUST be the fourth element of this struct! */
- zend_uint fn_flags; /* MUST be the fifth element of this struct! */
+ /* Common elements */
+ zend_uchar type;
+ zend_uchar *arg_types;
+ char *function_name;
+ zend_class_entry *scope;
+ zend_uint fn_flags;
zend_namespace *ns;
+ union _zend_function *prototype;
+ /* END of common elements */
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
} zend_internal_function;
@@ -177,6 +181,7 @@
zend_class_entry *scope;
zend_uint fn_flags;
zend_namespace *ns;
+ union _zend_function *prototype;
} common;
zend_op_array op_array;