Index: zend_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.296.2.27.2.34.2.33
diff -u -r1.296.2.27.2.34.2.33 zend_API.c
--- zend_API.c	25 Mar 2008 13:04:03 -0000	1.296.2.27.2.34.2.33
+++ zend_API.c	4 May 2008 20:19:34 -0000
@@ -1038,8 +1038,13 @@
 	zval *tmp;
 	zend_object *object;
 
-	if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
-		char *what = class_type->ce_flags & ZEND_ACC_INTERFACE ? "interface" : "abstract class";
+	if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_STATIC_CLASS)) {
+		char *what;
+		if (class_type->ce_flags & ZEND_ACC_INTERFACE) {
+			what = "interface";
+		} else {
+			what = class_type->ce_flags & ZEND_ACC_STATIC_CLASS ? "static class" : "abstract class";
+		}
 		zend_error(E_ERROR, "Cannot instantiate %s %s", what, class_type->name);
 	}
 
Index: zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.647.2.27.2.41.2.60
diff -u -r1.647.2.27.2.41.2.60 zend_compile.c
--- zend_compile.c	29 Apr 2008 08:15:16 -0000	1.647.2.27.2.41.2.60
+++ zend_compile.c	4 May 2008 20:19:34 -0000
@@ -2638,6 +2638,9 @@
 	if (parent_ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
 		zend_error(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name, parent_ce->name);
 	}
+	if (!(ce->type == ZEND_INTERNAL_CLASS) && (ce->ce_flags & ZEND_ACC_STATIC_CLASS) && !(parent_ce->ce_flags & ZEND_ACC_STATIC_CLASS)) {
+		zend_error(E_COMPILE_ERROR, "Class %s may not strengthen interface. Parent class (%s) is non-static and %s is static", ce->name, parent_ce->name, ce->name);
+	}
 
 	ce->parent = parent_ce;
 	/* Inherit interfaces */
@@ -3283,6 +3286,15 @@
 }
 
 
+static void do_verify_static_class(TSRMLS_D)
+{
+	zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+	opline->opcode = ZEND_VERIFY_STATIC_CLASS;
+	opline->op1 = CG(implementing_class);
+	SET_UNUSED(opline->op2);
+}
+
 void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRMLS_DC)
 {
 	zend_class_entry *ce = CG(active_class_entry);
@@ -3310,12 +3322,17 @@
 
 	ce->line_end = zend_get_compiled_lineno(TSRMLS_C);
 
-	if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))
+	if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_STATIC_CLASS))
 		&& ((parent_token->op_type != IS_UNUSED) || (ce->num_interfaces > 0))) {
 		zend_verify_abstract_class(ce TSRMLS_CC);
 		if (ce->parent || ce->num_interfaces) {
 			do_verify_abstract_class(TSRMLS_C);
 		}
+	} else if (ce->ce_flags & ZEND_ACC_STATIC_CLASS) {
+		zend_verify_static_class(ce TSRMLS_CC);
+		if (ce->parent || ce->num_interfaces) {
+			do_verify_static_class(TSRMLS_C);
+		}
 	}
 	/* Inherit interfaces; reset number to zero, we need it for above check and
 	 * will restore it during actual implementation. 
Index: zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.316.2.8.2.12.2.21
diff -u -r1.316.2.8.2.12.2.21 zend_compile.h
--- zend_compile.h	29 Mar 2008 11:52:10 -0000	1.316.2.8.2.12.2.21
+++ zend_compile.h	4 May 2008 20:19:34 -0000
@@ -119,6 +119,7 @@
 #define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS	0x20
 #define ZEND_ACC_FINAL_CLASS	            0x40
 #define ZEND_ACC_INTERFACE		            0x80
+#define ZEND_ACC_STATIC_CLASS				0x100000
 
 /* op_array flags */
 #define ZEND_ACC_INTERACTIVE				0x10
Index: zend_execute.h
===================================================================
RCS file: /repository/ZendEngine2/zend_execute.h,v
retrieving revision 1.84.2.4.2.8.2.9
diff -u -r1.84.2.4.2.8.2.9 zend_execute.h
--- zend_execute.h	15 Apr 2008 15:52:36 -0000	1.84.2.4.2.8.2.9
+++ zend_execute.h	4 May 2008 20:19:34 -0000
@@ -305,6 +305,7 @@
 ZEND_API void zend_timeout(int dummy);
 ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC);
 void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
+void zend_verify_static_class(zend_class_entry *ce TSRMLS_DC);
 
 #ifdef ZEND_WIN32
 void zend_init_timeout_thread(void);
Index: zend_execute_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute_API.c,v
retrieving revision 1.331.2.20.2.24.2.37
diff -u -r1.331.2.20.2.24.2.37 zend_execute_API.c
--- zend_execute_API.c	29 Apr 2008 09:18:14 -0000	1.331.2.20.2.24.2.37
+++ zend_execute_API.c	4 May 2008 20:19:34 -0000
@@ -1688,35 +1688,37 @@
 }
 /* }}} */
 
-#define MAX_ABSTRACT_INFO_CNT 3
-#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
-#define DISPLAY_ABSTRACT_FN(idx) \
-	ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \
-	ai.afn[idx] ? "::" : "", \
-	ai.afn[idx] ? ai.afn[idx]->common.function_name : "", \
-	ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
+#define MAX_INSPECTION_INFO_CNT 3
+#define MAX_INSPECTION_INFO_FMT "%s%s%s%s"
+#define DISPLAY_INSPECTION_INFO_FN(idx) \
+	cii.afn[idx] ? ZEND_FN_SCOPE_NAME(cii.afn[idx]) : "", \
+	cii.afn[idx] ? "::" : "", \
+	cii.afn[idx] ? cii.afn[idx]->common.function_name : "", \
+	cii.afn[idx] && cii.afn[idx + 1] ? ", " : (cii.afn[idx] && cii.cnt > MAX_INSPECTION_INFO_CNT ? ", ..." : "")
 
-typedef struct _zend_abstract_info {
-	zend_function *afn[MAX_ABSTRACT_INFO_CNT + 1];
+typedef struct _zend_class_inspection_info {
+	zend_function *afn[MAX_INSPECTION_INFO_CNT + 1];
 	int cnt;
 	int ctor;
-} zend_abstract_info;
+	int ce_flag;
+	int ce_flag_condition;
+} zend_class_inspection_info;
 
-static int zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai TSRMLS_DC) /* {{{ */
+static int zend_verify_class_function(zend_function *fn, zend_class_inspection_info *cii TSRMLS_DC) /* {{{ */
 {
-	if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
-		if (ai->cnt < MAX_ABSTRACT_INFO_CNT) {
-			ai->afn[ai->cnt] = fn;
+	if ((fn->common.fn_flags & cii->ce_flag) == cii->ce_flag_condition) {
+		if (cii->cnt < MAX_INSPECTION_INFO_CNT) {
+			cii->afn[cii->cnt] = fn;
 		}
 		if (fn->common.fn_flags & ZEND_ACC_CTOR) {
-			if (!ai->ctor) {
-				ai->cnt++;
-				ai->ctor = 1;
+			if (!cii->ctor) {
+				cii->cnt++;
+				cii->ctor = 1;
 			} else {
-				ai->afn[ai->cnt] = NULL;
+				cii->afn[cii->cnt] = NULL;
 			}
 		} else {
-			ai->cnt++;
+			cii->cnt++;
 		}
 	}
 	return 0;
@@ -1725,21 +1727,46 @@
 
 void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */
 {
-	zend_abstract_info ai;
+	zend_class_inspection_info cii;
 
 	if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
-		memset(&ai, 0, sizeof(ai));
+		memset(&cii, 0, sizeof(cii));
 
-		zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_abstract_class_function, &ai TSRMLS_CC);
+		cii.ce_flag = ZEND_ACC_ABSTRACT;
+		cii.ce_flag_condition = 2;
+		zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_class_function, &cii TSRMLS_CC);
+
+		if (cii.cnt) {
+			zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_INSPECTION_INFO_FMT MAX_INSPECTION_INFO_FMT MAX_INSPECTION_INFO_FMT ")",
+				ce->name, cii.cnt,
+				cii.cnt > 1 ? "s" : "",
+				DISPLAY_INSPECTION_INFO_FN(0),
+				DISPLAY_INSPECTION_INFO_FN(1),
+				DISPLAY_INSPECTION_INFO_FN(2)
+			);
+		}
+	}
+}
+/* }}} */
+
+void zend_verify_static_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */
+{
+	zend_class_inspection_info cii;
 
-		if (ai.cnt) {
-			zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
-				ce->name, ai.cnt,
-				ai.cnt > 1 ? "s" : "",
-				DISPLAY_ABSTRACT_FN(0),
-				DISPLAY_ABSTRACT_FN(1),
-				DISPLAY_ABSTRACT_FN(2)
-				);
+	if (ce->ce_flags & ZEND_ACC_STATIC_CLASS) {
+		memset(&cii, 0, sizeof(cii));
+		cii.ce_flag = ZEND_ACC_STATIC;
+		cii.ce_flag_condition = 0;
+		zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_class_function, &cii TSRMLS_CC);
+
+		if (cii.cnt) {
+			zend_error(E_ERROR, "Static class %s contains %d non-static method%s that must be declared static (" MAX_INSPECTION_INFO_FMT MAX_INSPECTION_INFO_FMT MAX_INSPECTION_INFO_FMT ")",
+				ce->name, cii.cnt,
+				cii.cnt > 1 ? "s" : "",
+				DISPLAY_INSPECTION_INFO_FN(0),
+				DISPLAY_INSPECTION_INFO_FN(1),
+				DISPLAY_INSPECTION_INFO_FN(2)
+			);
 		}
 	}
 }
Index: zend_language_parser.y
===================================================================
RCS file: /repository/ZendEngine2/zend_language_parser.y,v
retrieving revision 1.160.2.4.2.8.2.19
diff -u -r1.160.2.4.2.8.2.19 zend_language_parser.y
--- zend_language_parser.y	28 Mar 2008 14:34:59 -0000	1.160.2.4.2.8.2.19
+++ zend_language_parser.y	4 May 2008 20:19:35 -0000
@@ -316,6 +316,8 @@
 
 class_entry_type:
 		T_CLASS			{ $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = 0; }
+	|	T_STATIC T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = ZEND_ACC_STATIC_CLASS; }
+	|	T_ABSTRACT T_STATIC T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = ZEND_ACC_STATIC_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
 	|	T_ABSTRACT T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
 	|	T_FINAL T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = ZEND_ACC_FINAL_CLASS; }
 ;
Index: zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.59.2.29.2.48.2.51
diff -u -r1.59.2.29.2.48.2.51 zend_vm_def.h
--- zend_vm_def.h	30 Apr 2008 10:44:08 -0000	1.59.2.29.2.48.2.51
+++ zend_vm_def.h	4 May 2008 20:19:35 -0000
@@ -2697,13 +2697,13 @@
 	zval *object_zval;
 	zend_function *constructor;
 
-	if (EX_T(opline->op1.u.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
+	if (EX_T(opline->op1.u.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_STATIC_CLASS)) {
 		char *class_type;
 
 		if (EX_T(opline->op1.u.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) {
 			class_type = "interface";
 		} else {
-			class_type = "abstract class";
+			class_type = EX_T(opline->op1.u.var).class_entry->ce_flags & ZEND_ACC_STATIC_CLASS ? "static class" : "abstract class";
 		}
 		zend_error_noreturn(E_ERROR, "Cannot instantiate %s %s", class_type,  EX_T(opline->op1.u.var).class_entry->name);
 	}
@@ -4157,6 +4157,12 @@
 	ZEND_VM_NEXT_OPCODE();
 }
 
+ZEND_VM_HANDLER(151, ZEND_VERIFY_STATIC_CLASS, ANY, ANY)
+{
+	zend_verify_static_class(EX_T(EX(opline)->op1.u.var).class_entry TSRMLS_CC);
+	ZEND_VM_NEXT_OPCODE();
+}
+
 ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
 {
 	int ret = zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL);
Index: zend_vm_execute.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_execute.h,v
retrieving revision 1.62.2.30.2.49.2.50
diff -u -r1.62.2.30.2.49.2.50 zend_vm_execute.h
--- zend_vm_execute.h	30 Apr 2008 10:44:08 -0000	1.62.2.30.2.49.2.50
+++ zend_vm_execute.h	4 May 2008 20:19:37 -0000
@@ -331,13 +331,13 @@
 	zval *object_zval;
 	zend_function *constructor;
 
-	if (EX_T(opline->op1.u.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
+	if (EX_T(opline->op1.u.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS|ZEND_ACC_STATIC_CLASS)) {
 		char *class_type;
 
 		if (EX_T(opline->op1.u.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) {
 			class_type = "interface";
 		} else {
-			class_type = "abstract class";
+			class_type = EX_T(opline->op1.u.var).class_entry->ce_flags & ZEND_ACC_STATIC_CLASS ? "static class" : "abstract class";
 		}
 		zend_error_noreturn(E_ERROR, "Cannot instantiate %s %s", class_type,  EX_T(opline->op1.u.var).class_entry->name);
 	}
@@ -549,6 +549,12 @@
 	ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+	zend_verify_static_class(EX_T(EX(opline)->op1.u.var).class_entry TSRMLS_CC);
+	ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	int ret = zend_user_opcode_handlers[EX(opline)->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL);
@@ -33292,31 +33298,31 @@
   	ZEND_USER_OPCODE_SPEC_HANDLER,
   	ZEND_USER_OPCODE_SPEC_HANDLER,
   	ZEND_USER_OPCODE_SPEC_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
-  	ZEND_NULL_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
+  	ZEND_VERIFY_STATIC_CLASS_SPEC_HANDLER,
   	ZEND_JMP_SET_SPEC_CONST_HANDLER,
   	ZEND_JMP_SET_SPEC_CONST_HANDLER,
   	ZEND_JMP_SET_SPEC_CONST_HANDLER,
Index: zend_vm_opcodes.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_opcodes.h,v
retrieving revision 1.42.2.17.2.1.2.6
diff -u -r1.42.2.17.2.1.2.6 zend_vm_opcodes.h
--- zend_vm_opcodes.h	28 Mar 2008 14:35:01 -0000	1.42.2.17.2.1.2.6
+++ zend_vm_opcodes.h	4 May 2008 20:19:37 -0000
@@ -151,4 +151,5 @@
 #define ZEND_ISSET_ISEMPTY_PROP_OBJ          148
 #define ZEND_HANDLE_EXCEPTION                149
 #define ZEND_USER_OPCODE                     150
+#define ZEND_VERIFY_STATIC_CLASS             151
 #define ZEND_JMP_SET                         152
