- Nuke memory leak.
struct _zend_class_entry *parent;
int *refcount;
zend_bool constants_updated;
+ zend_bool is_namespace;
HashTable function_table;
HashTable default_properties;
class_entry->refcount = (int *) malloc(sizeof(int));
*class_entry->refcount = 1;
class_entry->constants_updated = 0;
+ class_entry->is_namespace = 0;
zend_hash_init(&class_entry->default_properties, 0, NULL, ZVAL_PTR_DTOR, 1);
zend_hash_init(&class_entry->static_members, 0, NULL, ZVAL_PTR_DTOR, 1);
zend_hash_init(&class_entry->constants, 0, NULL, ZVAL_PTR_DTOR, 1);
zend_str_tolower(function_name->u.constant.value.str.val, function_name->u.constant.value.str.len);
if (zend_hash_find(CG(function_table), function_name->u.constant.value.str.val, function_name->u.constant.value.str.len+1, (void **) &function)==FAILURE) {
- znode tmp = *function_name;
-
- zval_copy_ctor(&tmp.u.constant);
- zend_do_begin_dynamic_function_call(&tmp TSRMLS_CC);
+ zend_do_begin_dynamic_function_call(function_name TSRMLS_CC);
return 1; /* Dynamic */
}
}
-void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name TSRMLS_DC)
+void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name, zend_bool is_namespace TSRMLS_DC)
{
zend_op *opline;
int runtime_inheritance = 0;
new_class_entry.refcount = (int *) emalloc(sizeof(int));
*new_class_entry.refcount = 1;
new_class_entry.constants_updated = 0;
+ new_class_entry.is_namespace = is_namespace;
zend_str_tolower(new_class_entry.name, new_class_entry.name_length);
void zend_do_case_after_statement(znode *result, znode *case_token TSRMLS_DC);
void zend_do_default_before_statement(znode *case_list, znode *default_token TSRMLS_DC);
-void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name TSRMLS_DC);
+void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name, zend_bool is_namespace TSRMLS_DC);
void zend_do_end_class_declaration(znode *class_token TSRMLS_DC);
void zend_do_declare_property(znode *var_name, znode *value, int declaration_type TSRMLS_DC);
switch (opline->extended_value) {
case ZEND_FETCH_LOCAL:
- //target_symbol_table = EG(active_symbol_table);
- target_symbol_table = EG(namespace)?&EG(namespace)->static_members:EG(active_symbol_table);
+ target_symbol_table = EG(active_symbol_table);
break;
case ZEND_FETCH_GLOBAL:
if (opline->op1.op_type == IS_VAR) {
object_info object;
temp_variable *Ts;
zend_bool original_in_execution;
+ zend_class_entry *calling_namespace;
} zend_execute_data;
#define EX(element) execute_data.element
convert_to_string(&tmp);
function_name = &tmp;
zend_str_tolower(tmp.value.str.val, tmp.value.str.len);
-
+
+ EX(calling_namespace) = EG(namespace);
if (EX(opline)->op1.op_type != IS_UNUSED) {
if (EX(opline)->op1.op_type==IS_CONST) { /* used for class::function() */
zval **object_ptr_ptr;
EX(object).ptr = *object_ptr_ptr;
EX(object).ptr->refcount++; /* For this pointer */
}
- active_function_table = &EX(Ts)[EX(opline)->op1.u.var].EA.class_entry->function_table;
+
+ {
+ zend_class_entry *ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry;
+ active_function_table = &ce->function_table;
+ if (ce->is_namespace) {
+ EX(calling_namespace) = ce;
+ }
+ }
} else { /* used for member function calls */
EX(object).ptr = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
do_fcall_common:
{
zval **original_return_value;
+ zend_class_entry *current_namespace;
int return_value_used = RETURN_VALUE_USED(EX(opline));
zend_ptr_stack_n_push(&EG(argument_stack), 2, (void *) EX(opline)->extended_value, NULL);
+ current_namespace = EG(namespace);
+ EG(namespace) = EX(calling_namespace);
EX(Ts)[EX(opline)->result.u.var].var.ptr_ptr = &EX(Ts)[EX(opline)->result.u.var].var.ptr;
EG(function_state_ptr) = &EX(function_state);
zend_ptr_stack_clear_multiple(TSRMLS_C);
+ EG(namespace) = current_namespace;
+
if (EG(exception)) {
if (EX(opline)->op2.u.opline_num == -1) {
RETURN_FROM_EXECUTE_LOOP(execute_data);
NEXT_OPCODE();
case ZEND_NEW:
{
+ if (EX(Ts)[EX(opline)->op1.u.var].EA.class_entry->is_namespace) {
+ zend_error(E_ERROR, "Cannot instantiate a namespace");
+ }
EX(Ts)[EX(opline)->result.u.var].var.ptr_ptr = &EX(Ts)[EX(opline)->result.u.var].var.ptr;
ALLOC_ZVAL(EX(Ts)[EX(opline)->result.u.var].var.ptr);
object_init_ex(EX(Ts)[EX(opline)->result.u.var].var.ptr, EX(Ts)[EX(opline)->op1.u.var].EA.class_entry);
T_CATCH '(' T_VARIABLE ')' { zend_do_begin_catch(&$1, &$8 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
| T_THROW expr ';' { zend_do_throw(&$2 TSRMLS_CC); }
| T_DELETE cvar ';' { zend_do_end_variable_parse(BP_VAR_UNSET, 0 TSRMLS_CC); zend_do_unset(&$1, ZEND_UNSET_OBJ TSRMLS_CC); }
- | T_NAMESPACE namespace_class_entry { do_namespace(&$2 TSRMLS_CC); }
+ | T_NAMESPACE namespace_class_entry ';' { do_namespace(&$2 TSRMLS_CC); }
| T_NAMESPACE ';' { do_namespace(NULL TSRMLS_CC); }
;
'(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
| T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 0, $3.op_type TSRMLS_CC); }
parameter_list '(' inner_statement_list ')' ';' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
- | T_CLASS T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
- | T_CLASS T_STRING T_EXTENDS T_STRING { zend_do_begin_class_declaration(&$1, &$2, &$4 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
+ | T_NAMESPACE T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL, 1 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
+ | T_CLASS T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL, 0 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
+ | T_CLASS T_STRING T_EXTENDS T_STRING { zend_do_begin_class_declaration(&$1, &$2, &$4, 0 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
;
parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
| T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 1, $3.op_type TSRMLS_CC); }
parameter_list '(' inner_statement_list ')' ';' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
- | T_CLASS T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
- | T_CLASS T_STRING T_EXTENDS T_STRING { zend_do_begin_class_declaration(&$1, &$2, &$4 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
+ | T_NAMESPACE T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL, 1 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
+ | T_CLASS T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL, 0 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
+ | T_CLASS T_STRING T_EXTENDS T_STRING { zend_do_begin_class_declaration(&$1, &$2, &$4, 0 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
;
is_reference: