]> granicus.if.org Git - php/commitdiff
- Implement declare() with declarables framework
authorZeev Suraski <zeev@php.net>
Mon, 24 Jan 2000 19:00:30 +0000 (19:00 +0000)
committerZeev Suraski <zeev@php.net>
Mon, 24 Jan 2000 19:00:30 +0000 (19:00 +0000)
- Implement ticks - Germany&Norway - 5 points!

12 files changed:
Zend/zend-parser.y
Zend/zend-scanner.l
Zend/zend.c
Zend/zend.h
Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_execute_API.c
Zend/zend_globals.h
Zend/zend_operators.c
Zend/zend_operators.h

index 93938dc39c8b797089c680b65976c609cd294dd3..aa20f4d5baceaafe0bdc88109a867850d3e5b826 100644 (file)
@@ -94,6 +94,8 @@
 %token T_ENDFOR
 %token T_FOREACH
 %token T_ENDFOREACH
+%token T_DECLARE
+%token T_ENDDECLARE
 %token T_AS
 %token T_SWITCH
 %token T_ENDSWITCH
@@ -160,6 +162,11 @@ inner_statement:
 
 
 statement:
+               unticked_statement { do_ticks(CLS_C); }
+;
+
+
+unticked_statement:
                '{' inner_statement_list '}'
        |       T_IF '(' expr ')' { do_if_cond(&$3, &$4 CLS_CC); } statement { do_if_after_statement(&$4, 1 CLS_CC); } elseif_list else_single { do_if_end(CLS_C); }
        |       T_IF '(' expr ')' ':' { do_if_cond(&$3, &$4 CLS_CC); } inner_statement_list { do_if_after_statement(&$4, 1 CLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { do_if_end(CLS_C); }
@@ -191,6 +198,7 @@ statement:
        |       T_USE use_filename ';'          { use_filename($2.u.constant.value.str.val, $2.u.constant.value.str.len CLS_CC); zval_dtor(&$2.u.constant); }
        |       T_UNSET '(' r_cvar ')' ';' { do_unset(&$3 CLS_CC); }
        |       T_FOREACH '(' expr T_AS { do_foreach_begin(&$1, &$3, &$2, &$4 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
+       |       T_DECLARE { do_declare_begin(CLS_C); } '(' declare_list ')' declare_statement { do_declare_end(CLS_C); }
        |       ';'             /* empty statement */
 ;
 
@@ -202,6 +210,11 @@ use_filename:
 
 
 declaration_statement:
+               unticked_declaration_statement  { do_ticks(CLS_C); }
+;
+
+
+unticked_declaration_statement:
                T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { do_begin_function_declaration(&$1, &$4, 0, $3.op_type CLS_CC); }
                        '(' parameter_list ')' '{' inner_statement_list '}' { do_end_function_declaration(&$1 CLS_CC); }
        |       T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING  { do_begin_function_declaration(&$1, &$4, 0, $3.op_type CLS_CC); }
@@ -229,6 +242,18 @@ foreach_statement:
 ;
 
 
+declare_statement:
+               statement
+       |       ':' inner_statement_list T_ENDDECLARE ';'
+;
+
+
+declare_list:
+               T_STRING '=' static_scalar                                              { do_declare_stmt(&$1, &$3 CLS_CC); }
+       |       declare_list ',' T_STRING '=' static_scalar             { do_declare_stmt(&$3, &$5 CLS_CC); }
+;
+
+
 switch_case_list:
                '{' case_list '}'                                       { $$ = $2; }
        |       '{' ';' case_list '}'                           { $$ = $3; }
index 42d9c90c85f872829f48a6ade612d465c27546cf..2755dae5119330da500bbd51d764a12ce1a5be8d 100644 (file)
@@ -780,6 +780,14 @@ ESCAPED_AND_WHITESPACE [\n\t\r #'.:;,()|^&+-/*=%!~<>?@]+
        return T_ENDFOREACH;
 }
 
+<ST_IN_SCRIPTING>"declare" {
+       return T_DECLARE;
+}
+
+<ST_IN_SCRIPTING>"enddeclare" {
+       return T_ENDDECLARE;
+}
+
 <ST_IN_SCRIPTING>"as" {
        return T_AS;
 }
index ba07725523efe471adc8678e49afddbc06d88447..24b65256339745240ec6f97ff35d8b6af940bdcf 100644 (file)
@@ -48,6 +48,7 @@ ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
 ZEND_API void (*zend_block_interruptions)(void);
 ZEND_API void (*zend_unblock_interruptions)(void);
 ZEND_API int (*zend_get_ini_entry)(char *name, uint name_length, zval *contents);
+void (*zend_ticks_function)(int ticks);
 
 #ifdef ZTS
 ZEND_API int compiler_globals_id;
@@ -318,6 +319,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions)
        zend_block_interruptions = utility_functions->block_interruptions;
        zend_unblock_interruptions = utility_functions->unblock_interruptions;
        zend_get_ini_entry = utility_functions->get_ini_entry;
+       zend_ticks_function = utility_functions->ticks_function;
 
        zend_compile_files = compile_files;
        zend_execute = execute;
index bfcf96d70aaf28a7ca6f6b651dc0cc8bae20ee6e..ed306c2bbd37cb9eec322220767d3f58c41b858c 100644 (file)
@@ -204,6 +204,7 @@ typedef struct _zend_utility_functions {
        void (*block_interruptions)(void);
        void (*unblock_interruptions)(void);
        int (*get_ini_entry)(char *name, uint name_length, zval *contents);
+       void (*ticks_function)(int ticks);
 } zend_utility_functions;
 
                
@@ -283,6 +284,7 @@ extern ZEND_API void (*zend_block_interruptions)(void);
 extern ZEND_API void (*zend_unblock_interruptions)(void);
 extern ZEND_API void (*zend_message_dispatcher)(long message, void *data);
 extern ZEND_API int (*zend_get_ini_entry)(char *name, uint name_length, zval *contents);
+extern void (*zend_ticks_function)(int ticks);
  
 void zenderror(char *error);
 
index 2dbe69b91417dc54f7a31afdaaa398edb134450e..b828a8bd7f98b62bc30b332e2045e5353309c461 100644 (file)
@@ -196,7 +196,7 @@ ZEND_FUNCTION(strcmp)
        }
        convert_to_string_ex(s1);
        convert_to_string_ex(s2);
-       RETURN_LONG(zend_binary_strcmp(*s1,*s2));
+       RETURN_LONG(zend_binary_zval_strcmp(*s1,*s2));
 }
 /* }}} */
 
@@ -211,7 +211,7 @@ ZEND_FUNCTION(strcasecmp)
        }
        convert_to_string_ex(s1);
        convert_to_string_ex(s2);
-       RETURN_LONG(zend_binary_strcasecmp(*s1, *s2));
+       RETURN_LONG(zend_binary_zval_strcasecmp(*s1, *s2));
 }
 /* }}} */
 
index 48f5eafcde8996e74c6f73b6619b8afd3a627be4..664141093d515069720090558c11d393c15ba160 100644 (file)
@@ -85,6 +85,13 @@ static void zend_open_file_dtor_wrapper(zend_file_handle *fh)
 }
 
 
+static void init_compiler_declarables(CLS_D ELS_DC)
+{
+       CG(declarables).ticks.type = IS_LONG;
+       CG(declarables).ticks.value.lval = 0;
+}
+
+
 void init_compiler(CLS_D ELS_DC)
 {
        zend_stack_init(&CG(bp_stack));
@@ -92,6 +99,7 @@ void init_compiler(CLS_D ELS_DC)
        zend_stack_init(&CG(switch_cond_stack));
        zend_stack_init(&CG(foreach_copy_stack));
        zend_stack_init(&CG(object_stack));
+       zend_stack_init(&CG(declare_stack));
        CG(active_class_entry) = NULL;
        zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
        zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
@@ -104,6 +112,7 @@ void init_compiler(CLS_D ELS_DC)
        CG(unclean_shutdown) = 0;
        zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) zend_open_file_dtor, 0);
        zend_hash_init(&CG(used_files), 5, NULL, (void (*)(void *)) zend_open_file_dtor_wrapper, 0);
+       init_compiler_declarables(CLS_C ELS_CC);
 }
 
 
@@ -114,6 +123,7 @@ void shutdown_compiler(CLS_D)
        zend_stack_destroy(&CG(switch_cond_stack));
        zend_stack_destroy(&CG(foreach_copy_stack));
        zend_stack_destroy(&CG(object_stack));
+       zend_stack_destroy(&CG(declare_stack));
        zend_llist_destroy(&CG(filenames_list));
        zend_hash_apply(CG(function_table), (int (*)(void *)) is_not_internal_function);
        zend_hash_apply(CG(class_table), (int (*)(void *)) is_not_internal_class);
@@ -2034,6 +2044,33 @@ void do_foreach_end(znode *foreach_token, znode *open_brackets_token CLS_DC)
 }
 
 
+void do_declare_begin(CLS_D)
+{
+       zend_stack_push(&CG(declare_stack), &CG(declarables), sizeof(zend_declarables));
+}
+
+
+void do_declare_stmt(znode *var, znode *val CLS_DC)
+{
+       convert_to_string(&var->u.constant);
+
+       if (!zend_binary_strcasecmp(var->u.constant.value.str.val, var->u.constant.value.str.len, "ticks", sizeof("ticks")-1)) {
+               convert_to_long(&val->u.constant);
+               CG(declarables).ticks = val->u.constant;
+       }
+       zval_dtor(&var->u.constant);
+}
+
+
+void do_declare_end(CLS_D)
+{
+       zend_declarables *declarables;
+
+       zend_stack_top(&CG(declare_stack), (void **) &declarables);
+       CG(declarables) = *declarables;
+}
+
+
 void do_end_heredoc(CLS_D)
 {
        int opline_num = get_next_op_number(CG(active_op_array))-1;
@@ -2144,6 +2181,7 @@ void do_qm_false(znode *result, znode *false_value, znode *qm_token, znode *colo
        DEC_BPC(CG(active_op_array));
 }
 
+
 void do_extended_info(CLS_D)
 {
        zend_op *opline;
@@ -2159,6 +2197,7 @@ void do_extended_info(CLS_D)
        SET_UNUSED(opline->op2);
 }
 
+
 void do_extended_fcall_begin(CLS_D)
 {
        zend_op *opline;
@@ -2190,6 +2229,18 @@ void do_extended_fcall_end(CLS_D)
        SET_UNUSED(opline->op2);
 }
 
+void do_ticks(CLS_D)
+{
+       if (CG(declarables).ticks.value.lval) {
+               zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
+
+               opline->opcode = ZEND_TICKS;
+               opline->op1.u.constant = CG(declarables).ticks;
+               opline->op1.op_type = IS_CONST;
+               SET_UNUSED(opline->op2);
+       }
+}
+
 
 int zendlex(znode *zendlval CLS_DC)
 {
index 59ffd41009d55b13ae180e3046180d8c57cdf865..9e331aac31911fa60b5a48eb8c778977fcf65aaf 100644 (file)
@@ -328,6 +328,10 @@ void do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_t
 void do_foreach_cont(znode *value, znode *key, znode *as_token CLS_DC);
 void do_foreach_end(znode *foreach_token, znode *open_brackets_token CLS_DC);
 
+void do_declare_begin(CLS_D);
+void do_declare_stmt(znode *var, znode *val CLS_DC);
+void do_declare_end(CLS_D);
+
 void do_end_heredoc(CLS_D);
 
 void do_exit(znode *result, znode *message CLS_DC);
@@ -343,6 +347,8 @@ void do_extended_info(CLS_D);
 void do_extended_fcall_begin(CLS_D);
 void do_extended_fcall_end(CLS_D);
 
+void do_ticks(CLS_D);
+
 #define INITIAL_OP_ARRAY_SIZE 64
 
 
@@ -511,6 +517,8 @@ int zendlex(znode *zendlval CLS_DC);
 #define ZEND_EXT_FCALL_END                     99
 #define ZEND_EXT_NOP                           100
 
+#define ZEND_TICKS                                     101
+
 /* end of block */
 
 
index 1bac5e2f9630cf0bda50dc5b83259d32534a2a52..0b15b0f8816547c80626ae37ce59dda8ec3edf65 100644 (file)
@@ -2245,6 +2245,14 @@ send_by_ref:
                        case ZEND_DECLARE_FUNCTION_OR_CLASS:
                                do_bind_function_or_class(opline, EG(function_table), EG(class_table), 0);
                                break;
+                       case ZEND_TICKS:
+                               if (++EG(ticks_count)==opline->op1.u.constant.value.lval) {
+                                       EG(ticks_count)=0;
+                                       if (zend_ticks_function) {
+                                               zend_ticks_function(opline->op1.u.constant.value.lval);
+                                       }
+                               }
+                               break;
                        case ZEND_EXT_NOP:
                        case ZEND_NOP:
                                break;
index 8c610ef30180240cf2ddcad1cff4132e44a9fbf8..912310a5552103b6a5ebb634469f69134edeacd8 100644 (file)
@@ -114,6 +114,8 @@ void init_executor(CLS_D ELS_DC)
        EG(suspend_garbage) = 0;
 
        zend_hash_init(&EG(imported_files), 5, NULL, NULL, 0);
+
+       EG(ticks_count) = 0;
 }
 
 
index aecd3778c7fef434a5ba280b274fccc2f134fb27..9592cb779021b046aeb61d2eceabfd23dedb4876 100644 (file)
@@ -58,12 +58,19 @@ END_EXTERN_C()
 
 /* excpt.h on Digital Unix 4.0 defines function_table */
 #undef function_table
-       
+
+
+typedef struct _zend_declarables {
+       zval ticks;
+} zend_declarables;
+
+
 struct _zend_compiler_globals {
        zend_stack bp_stack;
        zend_stack switch_cond_stack;
        zend_stack foreach_copy_stack;
        zend_stack object_stack;
+       zend_stack declare_stack;
 
        zend_class_entry class_entry, *active_class_entry;
 
@@ -93,6 +100,8 @@ struct _zend_compiler_globals {
        zend_bool asp_tags;
        zend_bool allow_call_time_pass_reference;
 
+       zend_declarables declarables;
+
        /* For extensions support */
        zend_bool extended_info;        /* generate extension information for debugger/profiler */
        zend_bool handle_op_arrays;     /* run op_arrays through op_array handlers */
@@ -152,6 +161,8 @@ struct _zend_executor_globals {
 
        long precision;
 
+       int ticks_count;
+
        /* for extended information support */
        zend_bool no_extensions;
 
index e8c7f2c801814f34b35d3de40adccb7dafdf6e3c..7bbf4ccc3f5ceb0b62b2f674d925a28674c58cdc 100644 (file)
@@ -1218,35 +1218,30 @@ ZEND_API void zend_str_tolower(char *str, unsigned int length)
 }
 
 
-ZEND_API int zend_binary_strcmp(zval *s1, zval *s2)
+ZEND_API int zend_binary_strcmp(char *s1, uint len1, char *s2, uint len2)
 {
        int retval;
        
-       retval = memcmp(s1->value.str.val, s2->value.str.val, MIN(s1->value.str.len,s2->value.str.len));
+       retval = memcmp(s1, s2, MIN(len1, len2));
        if (!retval) {
-               return (s1->value.str.len - s2->value.str.len);
+               return (len1 - len2);
        } else {
                return retval;
        }
 }
 
 
-ZEND_API int zend_binary_strcasecmp(zval *s1, zval *s2)
+ZEND_API int zend_binary_strcasecmp(char *s1, uint len1, char *s2, uint len2)
 {
-       const unsigned char *p1 = (const unsigned char *)s1->value.str.val;
-       const unsigned char *p2 = (const unsigned char *)s2->value.str.val;
        unsigned char c1 = 0, c2 = 0;
-       int len1, len2;
 
-       len1 = s1->value.str.len;
-       len2 = s2->value.str.len;
        if (len1 != len2 || !len1) {
                return len1 - len2;
        }
 
        while (len1--) {
-               c1 = tolower(*p1++);
-               c2 = tolower(*p2++);
+               c1 = tolower(*s1++);
+               c2 = tolower(*s2++);
                if (c1 != c2) {
                        break;
                }
@@ -1255,6 +1250,20 @@ ZEND_API int zend_binary_strcasecmp(zval *s1, zval *s2)
        return c1 - c2;
 }
 
+
+ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2)
+{
+       return zend_binary_strcmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len);
+}
+
+
+ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2)
+{
+       return zend_binary_strcasecmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len);
+}
+
+
+
 ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2)
 {
        int ret1,ret2;
@@ -1291,7 +1300,7 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2)
                        result->type = IS_LONG;
                }
        } else {
-               result->value.lval = zend_binary_strcmp(s1,s2);
+               result->value.lval = zend_binary_zval_strcmp(s1, s2);
                result->type = IS_LONG;
        }
        return; 
index a4378305b8b85fe122c61c22135a380e3d619b26..82c4f7cbd04b7c89260a71ba094a729ec27cc1b6 100644 (file)
@@ -69,8 +69,11 @@ ZEND_API int zval_is_true(zval *op);
 ZEND_API int compare_function(zval *result, zval *op1, zval *op2);
 
 ZEND_API void zend_str_tolower(char *str, unsigned int length);
-ZEND_API int zend_binary_strcmp(zval *s1, zval *s2);
-ZEND_API int zend_binary_strcasecmp(zval *s1, zval *s2);
+ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
+ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
+ZEND_API int zend_binary_strcmp(char *s1, uint len1, char *s2, uint len2);
+ZEND_API int zend_binary_strcasecmp(char *s1, uint len1, char *s2, uint len2);
+
 ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2);
 
 #define convert_to_long_ex(ppzv)                                                       \