@@ -74,7 +74,7 @@ void zend_init_compiler_data_structures(TSRMLS_D)
74
74
zend_stack_init (& CG (object_stack ));
75
75
zend_stack_init (& CG (declare_stack ));
76
76
CG (active_class_entry ) = NULL ;
77
- CG (active_ce_parent_class_name ). value . str . val = NULL ;
77
+ CG (active_namespace ) = & CG ( global_namespace ) ;
78
78
zend_llist_init (& CG (list_llist ), sizeof (list_llist_element ), NULL , 0 );
79
79
zend_llist_init (& CG (dimension_llist ), sizeof (int ), NULL , 0 );
80
80
zend_stack_init (& CG (list_stack ));
@@ -937,6 +937,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
937
937
op_array .fn_flags = fn_flags ;
938
938
939
939
op_array .scope = CG (active_class_entry );
940
+ op_array .namespace = CG (active_namespace );
940
941
941
942
if (is_method ) {
942
943
char * short_class_name = CG (active_class_entry )-> name ;
@@ -1150,7 +1151,7 @@ void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC)
1150
1151
}
1151
1152
1152
1153
1153
- void do_fetch_class (znode * result , znode * class_entry , znode * class_name TSRMLS_DC )
1154
+ void do_fetch_class (znode * result , znode * namespace_name , znode * class_name TSRMLS_DC )
1154
1155
{
1155
1156
long fetch_class_op_number ;
1156
1157
zend_op * opline ;
@@ -1159,8 +1160,9 @@ void do_fetch_class(znode *result, znode *class_entry, znode *class_name TSRMLS_
1159
1160
opline = get_next_op (CG (active_op_array ) TSRMLS_CC );
1160
1161
1161
1162
opline -> opcode = ZEND_FETCH_CLASS ;
1162
- if (class_entry ) {
1163
- opline -> op1 = * class_entry ;
1163
+ if (namespace_name ) {
1164
+ zend_str_tolower (namespace_name -> u .constant .value .str .val , namespace_name -> u .constant .value .str .len );
1165
+ opline -> op1 = * namespace_name ;
1164
1166
} else {
1165
1167
SET_UNUSED (opline -> op1 );
1166
1168
CG (catch_begin ) = fetch_class_op_number ;
@@ -1675,6 +1677,7 @@ static void create_class(HashTable *class_table, char *name, int name_length, ze
1675
1677
zend_initialize_class_data (new_class_entry , 1 );
1676
1678
1677
1679
zend_str_tolower (new_class_entry -> name , new_class_entry -> name_length );
1680
+
1678
1681
if (zend_hash_update (class_table , new_class_entry -> name , name_length + 1 , & new_class_entry , sizeof (zend_class_entry * ), NULL ) == FAILURE ) {
1679
1682
zend_error (E_COMPILE_ERROR , "Can't create class. Fatal error, please report!" );
1680
1683
}
@@ -1715,7 +1718,7 @@ static int create_nested_class(HashTable *class_table, char *path, zend_class_en
1715
1718
new_ce -> refcount ++ ;
1716
1719
if (zend_hash_add (& ce -> class_table , last , strlen (last )+ 1 , & new_ce , sizeof (zend_class_entry * ), NULL ) == FAILURE ) {
1717
1720
new_ce -> refcount -- ;
1718
- zend_error (E_COMPILE_ERROR , "Cannot redeclare class %s " , last );
1721
+ zend_error (E_COMPILE_ERROR , "Cannot redeclare class '%s' - class or namespace with this name already exist. " , last );
1719
1722
return FAILURE ;
1720
1723
}
1721
1724
return SUCCESS ;
@@ -1726,7 +1729,7 @@ ZEND_API int do_bind_function(zend_op *opline, HashTable *function_table, HashTa
1726
1729
zend_function * function ;
1727
1730
1728
1731
if (opline -> opcode != ZEND_DECLARE_FUNCTION ) {
1729
- zend_error (E_ERROR , "Internal compiler error. Please report!" );
1732
+ zend_error (E_COMPILE_ERROR , "Internal compiler error. Please report!" );
1730
1733
}
1731
1734
1732
1735
zend_hash_find (function_table , opline -> op1 .u .constant .value .str .val , opline -> op1 .u .constant .value .str .len , (void * ) & function );
@@ -1758,7 +1761,7 @@ ZEND_API int do_bind_class(zend_op *opline, HashTable *function_table, HashTable
1758
1761
zend_class_entry * ce , * * pce ;
1759
1762
1760
1763
if (zend_hash_find (class_table , opline -> op1 .u .constant .value .str .val , opline -> op1 .u .constant .value .str .len , (void * * ) & pce )== FAILURE ) {
1761
- zend_error (E_ERROR , "Internal Zend error - Missing class information for %s" , opline -> op1 .u .constant .value .str .val );
1764
+ zend_error (E_COMPILE_ERROR , "Internal Zend error - Missing class information for %s" , opline -> op1 .u .constant .value .str .val );
1762
1765
return FAILURE ;
1763
1766
} else {
1764
1767
ce = * pce ;
@@ -1769,7 +1772,7 @@ ZEND_API int do_bind_class(zend_op *opline, HashTable *function_table, HashTable
1769
1772
ce -> refcount ++ ;
1770
1773
if (zend_hash_add (class_table , opline -> op2 .u .constant .value .str .val , opline -> op2 .u .constant .value .str .len + 1 , & ce , sizeof (zend_class_entry * ), NULL )== FAILURE ) {
1771
1774
ce -> refcount -- ;
1772
- zend_error (E_ERROR , "Cannot redeclare class %s" , opline -> op2 .u .constant .value .str .val );
1775
+ zend_error (E_COMPILE_ERROR , "Cannot redeclare class %s" , opline -> op2 .u .constant .value .str .val );
1773
1776
return FAILURE ;
1774
1777
} else {
1775
1778
return SUCCESS ;
@@ -1784,7 +1787,7 @@ ZEND_API int do_bind_inherited_class(zend_op *opline, HashTable *function_table,
1784
1787
found_ce = zend_hash_find (class_table , opline -> op1 .u .constant .value .str .val , opline -> op1 .u .constant .value .str .len , (void * * ) & pce );
1785
1788
1786
1789
if (found_ce == FAILURE ) {
1787
- zend_error (E_ERROR , "Cannot redeclare class %s" , (* pce )-> name );
1790
+ zend_error (E_COMPILE_ERROR , "Cannot redeclare class %s" , (* pce )-> name );
1788
1791
return FAILURE ;
1789
1792
} else {
1790
1793
ce = * pce ;
@@ -1800,7 +1803,7 @@ ZEND_API int do_bind_inherited_class(zend_op *opline, HashTable *function_table,
1800
1803
1801
1804
/* Register the derived class */
1802
1805
if (zend_hash_add (class_table , opline -> op2 .u .constant .value .str .val , opline -> op2 .u .constant .value .str .len + 1 , pce , sizeof (zend_class_entry * ), NULL )== FAILURE ) {
1803
- zend_error (E_ERROR , "Cannot redeclare class %s" , opline -> op2 .u .constant .value .str .val );
1806
+ zend_error (E_COMPILE_ERROR , "Cannot redeclare class %s" , opline -> op2 .u .constant .value .str .val );
1804
1807
ce -> refcount -- ;
1805
1808
zend_hash_destroy (& ce -> function_table );
1806
1809
zend_hash_destroy (& ce -> default_properties );
@@ -2114,7 +2117,6 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
2114
2117
int doing_inheritance = 0 ;
2115
2118
zend_class_entry * new_class_entry = emalloc (sizeof (zend_class_entry ));
2116
2119
2117
- class_token -> u .previously_active_class_entry = CG (active_class_entry );
2118
2120
if (!(strcmp (class_name -> u .constant .value .str .val , "main" ) && strcmp (class_name -> u .constant .value .str .val , "self" ) &&
2119
2121
strcmp (class_name -> u .constant .value .str .val , "parent" ))) {
2120
2122
zend_error (E_COMPILE_ERROR , "Cannot use '%s' as class name as it is reserved" , class_name -> u .constant .value .str .val );
@@ -2148,7 +2150,7 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
2148
2150
opline -> op2 .op_type = IS_CONST ;
2149
2151
opline -> op2 .u .constant .type = IS_STRING ;
2150
2152
opline -> op2 .u .constant .refcount = 1 ;
2151
-
2153
+
2152
2154
if (doing_inheritance ) {
2153
2155
opline -> extended_value = parent_class_name -> u .var ;
2154
2156
opline -> opcode = ZEND_DECLARE_INHERITED_CLASS ;
@@ -2158,7 +2160,7 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
2158
2160
2159
2161
opline -> op2 .u .constant .value .str .val = estrndup (new_class_entry -> name , new_class_entry -> name_length );
2160
2162
opline -> op2 .u .constant .value .str .len = new_class_entry -> name_length ;
2161
-
2163
+
2162
2164
zend_hash_update (CG (class_table ), opline -> op1 .u .constant .value .str .val , opline -> op1 .u .constant .value .str .len , & new_class_entry , sizeof (zend_class_entry * ), NULL );
2163
2165
CG (active_class_entry ) = new_class_entry ;
2164
2166
}
@@ -2167,11 +2169,7 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
2167
2169
void zend_do_end_class_declaration (znode * class_token TSRMLS_DC )
2168
2170
{
2169
2171
do_inherit_parent_constructor (CG (active_class_entry ));
2170
- CG (active_class_entry ) = class_token -> u .previously_active_class_entry ;
2171
- if (CG (active_ce_parent_class_name ).value .str .val ) {
2172
- efree (CG (active_ce_parent_class_name ).value .str .val );
2173
- CG (active_ce_parent_class_name ).value .str .val = NULL ;
2174
- }
2172
+ CG (active_class_entry ) = NULL ;
2175
2173
}
2176
2174
2177
2175
void mangle_property_name (char * * dest , int * dest_length , char * src1 , int src1_length , char * src2 , int src2_length )
@@ -3180,6 +3178,116 @@ void zend_destroy_property_info(zend_property_info *property_info)
3180
3178
efree (property_info -> name );
3181
3179
}
3182
3180
3181
+ void zend_init_namespace (zend_namespace * ns TSRMLS_DC )
3182
+ {
3183
+ zend_hash_init (& ns -> function_table , 10 , NULL , ZEND_FUNCTION_DTOR , 0 );
3184
+ zend_hash_init (& ns -> class_table , 10 , NULL , ZEND_CLASS_DTOR , 0 );
3185
+ zend_hash_init (& ns -> constants_table , 10 , NULL , ZVAL_PTR_DTOR , 0 );
3186
+ ALLOC_HASHTABLE (ns -> static_members );
3187
+ zend_hash_init (ns -> static_members , 0 , NULL , ZVAL_PTR_DTOR , 0 );
3188
+ ns -> constructor = NULL ;
3189
+ ns -> type = ZEND_NAMESPACE ;
3190
+ }
3191
+
3192
+ void zend_do_begin_namespace (znode * ns_token , znode * ns_name TSRMLS_DC )
3193
+ {
3194
+ zend_namespace * ns = emalloc (sizeof (zend_namespace ));
3195
+ zend_op * opline ;
3196
+
3197
+ zend_str_tolower (ns_name -> u .constant .value .str .val , ns_name -> u .constant .value .str .len );
3198
+ ns -> name = ns_name -> u .constant .value .str .val ;
3199
+ ns -> name_length = ns_name -> u .constant .value .str .len ;
3200
+
3201
+ if (zend_hash_add (& CG (global_namespace ).class_table , ns -> name , ns -> name_length + 1 , (void * * )& ns , sizeof (zend_namespace * ), NULL ) != SUCCESS ) {
3202
+ efree (ns );
3203
+ zend_error (E_COMPILE_ERROR , "Cannot redefine namespace '%s' - class or namespace with this name already defined" , ns -> name );
3204
+ }
3205
+
3206
+ opline = get_next_op (CG (active_op_array ) TSRMLS_CC );
3207
+
3208
+ opline -> opcode = ZEND_DECLARE_NAMESPACE ;
3209
+ opline -> op1 .op_type = IS_CONST ;
3210
+ opline -> op1 .u .constant .type = IS_STRING ;
3211
+ opline -> op1 .u .constant .value .str .val = estrndup (ns -> name , ns -> name_length );
3212
+ opline -> op1 .u .constant .value .str .len = ns -> name_length ;
3213
+ opline -> op1 .u .constant .refcount = 1 ;
3214
+ SET_UNUSED (opline -> op2 );
3215
+
3216
+ zend_init_namespace (ns TSRMLS_CC );
3217
+
3218
+ ns -> constructor = emalloc (sizeof (zend_op_array ));
3219
+ init_op_array ((zend_op_array * )ns -> constructor , ZEND_USER_FUNCTION , INITIAL_OP_ARRAY_SIZE TSRMLS_CC );
3220
+ ns -> constructor -> op_array .namespace = CG (active_namespace );
3221
+
3222
+ ns_token -> u .op_array = CG (active_op_array );
3223
+
3224
+ CG (active_op_array ) = & ns -> constructor -> op_array ;
3225
+ CG (active_namespace ) = ns ;
3226
+
3227
+ /* new symbol tables */
3228
+ CG (class_table ) = & ns -> class_table ;
3229
+ CG (function_table ) = & ns -> function_table ;
3230
+
3231
+ fprintf (stderr , "Start namespace '%s'\n" , ns -> name );
3232
+ }
3233
+
3234
+ void zend_do_end_namespace (znode * ns_token TSRMLS_DC )
3235
+ {
3236
+ zend_namespace * ns = CG (active_op_array )-> namespace ;
3237
+ int handle = CG (handle_op_arrays );
3238
+
3239
+
3240
+ zend_do_return (NULL , 0 TSRMLS_CC );
3241
+ CG (handle_op_arrays ) = 0 ;
3242
+ pass_two (CG (active_op_array ) TSRMLS_CC );
3243
+ CG (handle_op_arrays ) = handle ;
3244
+
3245
+ CG (active_op_array )-> namespace = CG (active_namespace );
3246
+
3247
+ CG (active_namespace ) = ns ;
3248
+ CG (active_op_array ) = ns_token -> u .op_array ;
3249
+ /* restore symbol tables */
3250
+ CG (class_table ) = & CG (active_namespace )-> class_table ;
3251
+ CG (function_table ) = & CG (active_namespace )-> function_table ;
3252
+
3253
+ fprintf (stderr , "End namespace\n" );
3254
+ }
3255
+
3256
+ void zend_do_declare_namespace_var (znode * var_name , znode * value TSRMLS_DC )
3257
+ {
3258
+ zval * var ;
3259
+
3260
+ ALLOC_ZVAL (var );
3261
+
3262
+ if (value ) {
3263
+ * var = value -> u .constant ;
3264
+ } else {
3265
+ INIT_PZVAL (var );
3266
+ var -> type = IS_NULL ;
3267
+ }
3268
+
3269
+ zend_hash_update (CG (active_namespace )-> static_members , var_name -> u .constant .value .str .val , var_name -> u .constant .value .str .len + 1 , & var , sizeof (zval * ), NULL );
3270
+
3271
+ FREE_PNODE (var_name );
3272
+ }
3273
+
3274
+ void zend_do_declare_namespace_constant (znode * var_name , znode * value TSRMLS_DC )
3275
+ {
3276
+ zval * var ;
3277
+
3278
+ ALLOC_ZVAL (var );
3279
+
3280
+ if (value ) {
3281
+ * var = value -> u .constant ;
3282
+ } else {
3283
+ INIT_PZVAL (var );
3284
+ var -> type = IS_NULL ;
3285
+ }
3286
+
3287
+ zend_hash_update (& CG (active_namespace )-> constants_table , var_name -> u .constant .value .str .val , var_name -> u .constant .value .str .len + 1 , & var , sizeof (zval * ), NULL );
3288
+
3289
+ FREE_PNODE (var_name );
3290
+ }
3183
3291
3184
3292
void zend_initialize_class_data (zend_class_entry * ce , zend_bool nullify_handlers )
3185
3293
{
@@ -3211,6 +3319,8 @@ void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers
3211
3319
ce -> __call = NULL ;
3212
3320
ce -> create_object = NULL ;
3213
3321
}
3322
+
3323
+ ce -> namespace = CG (active_namespace );
3214
3324
}
3215
3325
3216
3326
/*
0 commit comments