cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_execute.c zend_language_parser.y zend_language_scanner.l zend_operators.c zend_operators.h
| From: | Andrei Zmievski | Date: | Tue, 30 Jul 2002 04:07:15 +0000 |
| Subject: | cvs: ZendEngine2 / zend_compile.c zend_compile.h zend_execute.c zend_language_parser.y zend_language_scanner.l zend_operators.c zend_operators.h | ||
| Groups: | php.zend-engine.cvs | ||
| Request: | Send a blank email to php-zend-engine-cvs+get-281@lists.php.net to get a copy of this message | ||
andrei Tue Jul 30 00:07:15 2002 EDT
Modified files:
/ZendEngine2 zend_compile.c zend_compile.h zend_execute.c
zend_language_parser.y zend_language_scanner.l
zend_operators.c zend_operators.h
Log:
@- Adding 'is' operator that can be used to check the type of a variable,
@ or its class. (Andrei)
Index: ZendEngine2/zend_compile.c
diff -u ZendEngine2/zend_compile.c:1.297 ZendEngine2/zend_compile.c:1.298
--- ZendEngine2/zend_compile.c:1.297 Sat Jul 27 11:53:14 2002
+++ ZendEngine2/zend_compile.c Tue Jul 30 00:07:15 2002
@@ -2724,6 +2724,28 @@
}
+void zend_do_is_type(znode *result, znode *expr, znode *class, int type TSRMLS_DC)
+{
+ zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+ opline->opcode = ZEND_IS_TYPE;
+ opline->result.op_type = IS_TMP_VAR;
+ opline->result.u.var = get_temporary_variable(CG(active_op_array));
+ opline->op1 = *expr;
+
+ if (class) {
+ opline->op2 = *class;
+ opline->extended_value = 1;
+ } else {
+ opline->op2.u.constant.value.lval = type;
+ SET_UNUSED(opline->op2);
+ opline->extended_value = 0;
+ }
+
+ *result = opline->result;
+}
+
+
void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode
*as_token, int variable TSRMLS_DC)
{
zend_op *opline;
Index: ZendEngine2/zend_compile.h
diff -u ZendEngine2/zend_compile.h:1.178 ZendEngine2/zend_compile.h:1.179
--- ZendEngine2/zend_compile.h:1.178 Fri Jul 26 06:38:24 2002
+++ ZendEngine2/zend_compile.h Tue Jul 30 00:07:15 2002
@@ -358,6 +358,8 @@
void zend_do_unset(znode *variable TSRMLS_DC);
void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC);
+void zend_do_is_type(znode *result, znode *expr, znode *class, int type TSRMLS_DC);
+
void zend_do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode
*as_token, int variable TSRMLS_DC);
void zend_do_foreach_cont(znode *value, znode *key, znode *as_token TSRMLS_DC);
void zend_do_foreach_end(znode *foreach_token, znode *open_brackets_token TSRMLS_DC);
@@ -595,6 +597,9 @@
#define ZEND_ASSIGN_OBJ 136
#define ZEND_MAKE_VAR 137
+
+#define ZEND_IS_TYPE 138
+
/* end of block */
Index: ZendEngine2/zend_execute.c
diff -u ZendEngine2/zend_execute.c:1.354 ZendEngine2/zend_execute.c:1.355
--- ZendEngine2/zend_execute.c:1.354 Fri Jul 26 06:38:25 2002
+++ ZendEngine2/zend_execute.c Tue Jul 30 00:07:15 2002
@@ -3115,6 +3115,19 @@
}
}
NEXT_OPCODE();
+ case ZEND_IS_TYPE: {
+ zval *expr = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
+ if (EX(opline)->extended_value) {
+ is_type_function(&EX(Ts)[EX(opline)->result.u.var].tmp_var, expr,
+ EX(Ts)[EX(opline)->op2.u.var].EA.class_entry, 0 TSRMLS_CC);
+ } else {
+ is_type_function(&EX(Ts)[EX(opline)->result.u.var].tmp_var, expr,
+ NULL, EX(opline)->op2.u.constant.value.lval TSRMLS_CC);
+ }
+
+ FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
+ }
+ NEXT_OPCODE();
case ZEND_EXT_NOP:
case ZEND_NOP:
NEXT_OPCODE();
Index: ZendEngine2/zend_language_parser.y
diff -u ZendEngine2/zend_language_parser.y:1.64 ZendEngine2/zend_language_parser.y:1.65
--- ZendEngine2/zend_language_parser.y:1.64 Wed Jul 17 14:36:29 2002
+++ ZendEngine2/zend_language_parser.y Tue Jul 30 00:07:15 2002
@@ -67,7 +67,7 @@
%left '*' '/' '%'
%right '!' '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST
T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
%right '['
-%nonassoc T_NEW
+%nonassoc T_NEW T_IS_TYPE
%token T_EXIT
%token T_IF
%left T_ELSEIF
@@ -94,6 +94,7 @@
%token T_ENDFOREACH
%token T_DECLARE
%token T_ENDDECLARE
+%token T_IS_TYPE
%token T_AS
%token T_SWITCH
%token T_ENDSWITCH
@@ -528,6 +529,14 @@
| expr T_IS_SMALLER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$1,
&$3 TSRMLS_CC); }
| expr '>' expr { zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1
TSRMLS_CC); }
| expr T_IS_GREATER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3,
&$1 TSRMLS_CC); }
+ | expr T_IS_TYPE is_type_expr { zend_do_is_type(&$$, &$1, &$3, 0 TSRMLS_CC); }
+ | expr T_IS_TYPE T_INT_CAST { zend_do_is_type(&$$, &$1, NULL, IS_LONG TSRMLS_CC); }
+ | expr T_IS_TYPE T_DOUBLE_CAST { zend_do_is_type(&$$, &$1, NULL, IS_DOUBLE TSRMLS_CC); }
+ | expr T_IS_TYPE T_STRING_CAST { zend_do_is_type(&$$, &$1, NULL, IS_STRING TSRMLS_CC); }
+ | expr T_IS_TYPE T_ARRAY_CAST { zend_do_is_type(&$$, &$1, NULL, IS_ARRAY TSRMLS_CC); }
+ | expr T_IS_TYPE T_OBJECT_CAST { zend_do_is_type(&$$, &$1, NULL, IS_OBJECT TSRMLS_CC); }
+ | expr T_IS_TYPE T_BOOL_CAST { zend_do_is_type(&$$, &$1, NULL, IS_BOOL TSRMLS_CC); }
+ | expr T_IS_TYPE T_UNSET_CAST { zend_do_is_type(&$$, &$1, NULL, IS_NULL TSRMLS_CC); }
| '(' expr ')' { $$ = $2; }
| expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
expr ':' { zend_do_qm_true(&$4, &$2, &$5 TSRMLS_CC); }
@@ -585,6 +594,10 @@
| r_variable_without_static_member { $$ = $1; }
;
+is_type_expr:
+ parse_class_entry T_STRING { do_fetch_class(&$$, &$1, &$2 TSRMLS_CC); }
+ | T_STRING { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); }
+;
exit_expr:
/* empty */ { memset(&$$, 0, sizeof(znode)); $$.op_type = IS_UNUSED; }
Index: ZendEngine2/zend_language_scanner.l
diff -u ZendEngine2/zend_language_scanner.l:1.54 ZendEngine2/zend_language_scanner.l:1.55
--- ZendEngine2/zend_language_scanner.l:1.54 Tue Jul 16 15:11:14 2002
+++ ZendEngine2/zend_language_scanner.l Tue Jul 30 00:07:15 2002
@@ -555,6 +555,10 @@
return T_ENDDECLARE;
}
+<ST_IN_SCRIPTING>"is" {
+ return T_IS_TYPE;
+}
+
<ST_IN_SCRIPTING>"as" {
return T_AS;
}
Index: ZendEngine2/zend_operators.c
diff -u ZendEngine2/zend_operators.c:1.128 ZendEngine2/zend_operators.c:1.129
--- ZendEngine2/zend_operators.c:1.128 Mon Jul 15 14:11:04 2002
+++ ZendEngine2/zend_operators.c Tue Jul 30 00:07:15 2002
@@ -1365,6 +1365,60 @@
}
+ZEND_API int is_type_function(zval *result, zval *op1, zend_class_entry *class, int type TSRMLS_DC)
+{
+ if (class) {
+ if (Z_TYPE_P(op1) == IS_OBJECT) {
+ zend_class_entry *ce;
+ for (ce = Z_OBJCE_P(op1); ce != NULL; ce = ce->parent) {
+ if (ce == class) {
+ ZVAL_BOOL(result, 1);
+ return SUCCESS;
+ }
+ }
+ ZVAL_BOOL(result, 0);
+ } else {
+ ZVAL_BOOL(result, 0);
+ }
+ return SUCCESS;
+ }
+
+ switch (type) {
+ case IS_NULL:
+ ZVAL_BOOL(result, Z_TYPE_P(op1) == IS_NULL);
+ break;
+
+ case IS_LONG:
+ ZVAL_BOOL(result, Z_TYPE_P(op1) == IS_LONG);
+ break;
+
+ case IS_DOUBLE:
+ ZVAL_BOOL(result, Z_TYPE_P(op1) == IS_DOUBLE);
+ break;
+
+ case IS_STRING:
+ ZVAL_BOOL(result, Z_TYPE_P(op1) == IS_STRING);
+ break;
+
+ case IS_ARRAY:
+ ZVAL_BOOL(result, Z_TYPE_P(op1) == IS_ARRAY);
+ break;
+
+ case IS_OBJECT:
+ ZVAL_BOOL(result, Z_TYPE_P(op1) == IS_OBJECT);
+ break;
+
+ case IS_BOOL:
+ ZVAL_BOOL(result, Z_TYPE_P(op1) == IS_BOOL);
+ break;
+
+ default:
+ zend_error(E_ERROR, "Unknown operand type");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
#define LOWER_CASE 1
#define UPPER_CASE 2
#define NUMERIC 3
Index: ZendEngine2/zend_operators.h
diff -u ZendEngine2/zend_operators.h:1.56 ZendEngine2/zend_operators.h:1.57
--- ZendEngine2/zend_operators.h:1.56 Tue Apr 30 05:56:48 2002
+++ ZendEngine2/zend_operators.h Tue Jul 30 00:07:15 2002
@@ -58,6 +58,8 @@
ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
+ZEND_API int is_type_function(zval *result, zval *op1, zend_class_entry *ce, int type TSRMLS_DC);
+
static inline zend_bool is_numeric_string(char *str, int length, long *lval, double *dval,
zend_bool allow_errors)
{
long local_lval;