Skip to content

Commit ea327ea

Browse files
author
cpriest
committed
Removed code related to static accessors
This code was deemed to not work in all instances because the parent class definition is not always available at line-compile time fixes #4
1 parent 8483991 commit ea327ea

File tree

2 files changed

+0
-286
lines changed

2 files changed

+0
-286
lines changed

Zend/zend_compile.c

Lines changed: 0 additions & 255 deletions
Original file line numberDiff line numberDiff line change
@@ -745,101 +745,6 @@ void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) /*
745745
} else {
746746
zend_do_fetch_class(&class_node, class_name TSRMLS_CC);
747747
}
748-
749-
/* if(result->op_type == IS_CV) {
750-
Handle self::$Area accessors (normal and static)
751-
if(class_node.op_type == IS_VAR && class_node.EA == ZEND_FETCH_CLASS_SELF && CG(active_class_entry)) {
752-
753-
const char *member_name = CG(active_op_array)->vars[result->u.op.var].name;
754-
zend_accessor_info **aipp;
755-
756-
If the member_name is an accessor
757-
if(zend_hash_find((const HashTable *)&CG(active_class_entry)->accessors, member_name, strlen(member_name)+1, (void**)&aipp) == SUCCESS) {
758-
znode zn_self, zn_func, zn_arg_list;
759-
size_t member_name_len = strlen(member_name);
760-
761-
char *fname = strcatalloc("__get", 5, member_name, member_name_len TSRMLS_CC);
762-
763-
MAKE_ZNODEL(zn_self, "self", 4);
764-
ZVAL_LONG(&zn_arg_list.u.constant, 0);
765-
766-
MAKE_ZNODEL(zn_func, fname, 5 + member_name_len);
767-
efree(fname);
768-
769-
We assume we will be used as a getter, if zend_do_assign() is called, it will backpatch as calling a setter
770-
zend_do_begin_class_member_function_call(&zn_self, &zn_func TSRMLS_CC);
771-
zend_do_end_function_call(&zn_func, result, &zn_arg_list, 1, 0 TSRMLS_CC);
772-
zend_do_extended_fcall_end(TSRMLS_C);
773-
return;
774-
}
775-
}
776-
Handle parent::$Area accessors (normal and static)
777-
if(class_node.op_type == IS_VAR && class_node.EA == ZEND_FETCH_CLASS_PARENT && CG(active_class_entry) && CG(active_class_entry)->parent) {
778-
779-
const char *member_name = CG(active_op_array)->vars[result->u.op.var].name;
780-
zend_accessor_info **aipp;
781-
782-
If the member_name is an accessor
783-
if(zend_hash_find((const HashTable *)&CG(active_class_entry)->parent->accessors, member_name, strlen(member_name)+1, (void**)&aipp) == SUCCESS) {
784-
znode zn_parent, zn_func, zn_arg_list;
785-
size_t member_name_len = strlen(member_name);
786-
787-
char *fname = strcatalloc("__get", 5, member_name, member_name_len TSRMLS_CC);
788-
789-
MAKE_ZNODEL(zn_parent, "parent", 6);
790-
ZVAL_LONG(&zn_arg_list.u.constant, 0);
791-
792-
MAKE_ZNODEL(zn_func, fname, 5 + member_name_len);
793-
efree(fname);
794-
795-
We assume we will be used as a getter, if zend_do_assign() is called, it will backpatch as calling a setter
796-
zend_do_begin_class_member_function_call(&zn_parent, &zn_func TSRMLS_CC);
797-
zend_do_end_function_call(&zn_func, result, &zn_arg_list, 1, 0 TSRMLS_CC);
798-
zend_do_extended_fcall_end(TSRMLS_C);
799-
return;
800-
}
801-
}
802-
Handle Shape::$Area static accessor
803-
if(class_node.op_type == IS_CONST) {
804-
zend_class_entry **classpp;
805-
char *lcname = zend_str_tolower_dup(Z_STRVAL(class_node.u.constant), Z_STRLEN(class_node.u.constant));
806-
807-
if(zend_hash_find(CG(class_table), lcname, Z_STRLEN(class_node.u.constant)+1, (void**)&classpp) == SUCCESS) {
808-
ulong hash_value;
809-
zend_accessor_info **aipp;
810-
const char *member_name = CG(active_op_array)->vars[result->u.op.var].name;
811-
uint member_name_len = strlen(member_name);
812-
813-
hash_value = zend_hash_func(member_name, member_name_len+1);
814-
815-
if(zend_hash_quick_find(&(*classpp)->accessors, member_name, member_name_len+1, hash_value, (void**)&aipp) == SUCCESS
816-
&& ( (*aipp)->getter || (*aipp)->setter ) ) {
817-
znode zn_class, zn_func, zn_arg_list;
818-
819-
efree(lcname);
820-
821-
if(!((*aipp)->flags & ZEND_ACC_STATIC)) {
822-
zend_error(E_COMPILE_ERROR, "Cannot access non-static accessor %s::$%s in a static manner.", (*classpp)->name, member_name);
823-
}
824-
825-
MAKE_ZNODEL(zn_class, Z_STRVAL(class_node.u.constant), Z_STRLEN(class_node.u.constant));
826-
MAKE_ZNODE(zn_func, ((*aipp)->getter ? (*aipp)->getter->common.function_name : (*aipp)->setter->common.function_name));
827-
Z_STRVAL(zn_func.u.constant)[2] = 'g';
828-
ZVAL_LONG(&zn_arg_list.u.constant, 0);
829-
830-
We assume we will be used as a getter, if zend_do_assign() is called, it will backpatch as calling a setter
831-
zend_do_begin_class_member_function_call(&zn_class, &zn_func TSRMLS_CC);
832-
zend_do_end_function_call(&zn_func, result, &zn_arg_list, 1, 0 TSRMLS_CC);
833-
zend_do_extended_fcall_end(TSRMLS_C);
834-
zval_dtor(&class_node.u.constant);
835-
return;
836-
}
837-
}
838-
efree(lcname);
839-
}
840-
}*/
841-
842-
843748
zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
844749
if (result->op_type == IS_CV) {
845750
init_op(&opline TSRMLS_CC);
@@ -5458,29 +5363,13 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name
54585363
opline->op2_type = IS_CONST;
54595364

54605365
if (doing_inheritance) {
5461-
zend_op *fetch_class = NULL;
5462-
54635366
/* Make sure a trait does not try to extend a class */
54645367
if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
54655368
zend_error(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name);
54665369
}
54675370

54685371
opline->extended_value = parent_class_name->u.op.var;
54695372
opline->opcode = ZEND_DECLARE_INHERITED_CLASS;
5470-
5471-
/* Locate parent_class_name and parent_class_entry to assign */
5472-
fetch_class = find_previous_op(ZEND_FETCH_CLASS TSRMLS_CC);
5473-
5474-
if(fetch_class != NULL && fetch_class->op2_type == IS_CONST) {
5475-
zend_class_entry **parent_cepp = NULL;
5476-
zval *parent_class_zv = &CG(active_op_array)->literals[fetch_class->op2.constant].constant;
5477-
char *lc_parent_class = zend_str_tolower_dup(Z_STRVAL_P(parent_class_zv), Z_STRLEN_P(parent_class_zv));
5478-
5479-
if (zend_hash_find(CG(class_table), lc_parent_class, strlen(lc_parent_class)+1, (void **) &parent_cepp)==SUCCESS) {
5480-
new_class_entry->parent = *parent_cepp;
5481-
}
5482-
efree(lc_parent_class);
5483-
}
54845373
} else {
54855374
opline->opcode = ZEND_DECLARE_CLASS;
54865375
}
@@ -6559,47 +6448,6 @@ void zend_do_unset(const znode *variable TSRMLS_DC) /* {{{ */
65596448
last_op->opcode = ZEND_UNSET_OBJ;
65606449
SET_UNUSED(last_op->result);
65616450
break;
6562-
case ZEND_DO_FCALL_BY_NAME:
6563-
if((last_op-1)->opcode == ZEND_INIT_STATIC_METHOD_CALL) {
6564-
/* Capture unset() on static accessor call */
6565-
6566-
zend_op *initop = last_op-1;
6567-
6568-
/* Capture isset() on static accessor call */
6569-
const char *context_name; /* Does not need to be free'd */
6570-
6571-
zend_accessor_info *ai = zend_get_accessor_from_init_static_method_call(CG(active_op_array), initop, &context_name TSRMLS_CC);
6572-
if(ai) {
6573-
/* In the case of a getter, the getter call is not necessary, instead switch it to the name of the isset function, if present */
6574-
if(ai->unset) {
6575-
zval zv_unsetter;
6576-
zend_op *opline;
6577-
zend_del_literal(CG(active_op_array), initop->op2.constant+1);
6578-
zend_del_literal(CG(active_op_array), initop->op2.constant);
6579-
6580-
ZVAL_STRINGL(&zv_unsetter, ai->unset->common.function_name, strlen(ai->unset->common.function_name), 1);
6581-
initop->op2.constant = zend_add_func_name_literal(CG(active_op_array), &zv_unsetter TSRMLS_CC);
6582-
GET_CACHE_SLOT(initop->op2.constant);
6583-
6584-
/* Must free result of static __unsetHours() function call */
6585-
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
6586-
6587-
opline->opcode = ZEND_FREE;
6588-
opline->op1_type = last_op->result_type;
6589-
if (last_op->result_type == IS_CONST) {
6590-
opline->op1.constant = zend_add_literal(CG(active_op_array), &last_op->result.literal->constant TSRMLS_CC);
6591-
} else {
6592-
opline->op1 = last_op->result;
6593-
}
6594-
6595-
SET_UNUSED(opline->op2);
6596-
return;
6597-
} else if(!ai->setter) {
6598-
zend_error(E_COMPILE_ERROR, "Cannot unset property %s::$%s, no setter defined.", context_name, ZEND_ACC_NAME_AI(ai));
6599-
}
6600-
}
6601-
}
6602-
break;
66036451
}
66046452
}
66056453
}
@@ -6642,34 +6490,6 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC
66426490
case ZEND_FETCH_OBJ_IS:
66436491
last_op->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ;
66446492
break;
6645-
case ZEND_DO_FCALL_BY_NAME:
6646-
if((last_op-1)->opcode == ZEND_INIT_STATIC_METHOD_CALL) {
6647-
6648-
/* Capture isset() on static accessor call */
6649-
6650-
zend_op *initop = last_op-1;
6651-
6652-
/* Capture isset() on static accessor call */
6653-
const char *context_name; /* Does not need to be free'd */
6654-
6655-
zend_accessor_info *ai = zend_get_accessor_from_init_static_method_call(CG(active_op_array), initop, &context_name TSRMLS_CC);
6656-
if(ai) {
6657-
/* In the case of a getter, the getter call is not necessary, instead switch it to the name of the isset function, if present */
6658-
if(ai->isset) {
6659-
zval zv_issetter;
6660-
zend_del_literal(CG(active_op_array), initop->op2.constant+1);
6661-
zend_del_literal(CG(active_op_array), initop->op2.constant);
6662-
6663-
ZVAL_STRINGL(&zv_issetter, ai->isset->common.function_name, strlen(ai->isset->common.function_name), 1);
6664-
initop->op2.constant = zend_add_func_name_literal(CG(active_op_array), &zv_issetter TSRMLS_CC);
6665-
GET_CACHE_SLOT(initop->op2.constant);
6666-
return;
6667-
} else if(!ai->getter) {
6668-
zend_error(E_COMPILE_ERROR, "Cannot isset property %s::$%s, no getter defined.", context_name, ZEND_ACC_NAME_AI(ai));
6669-
}
6670-
}
6671-
}
6672-
break;
66736493
}
66746494
}
66756495
last_op->result_type = IS_TMP_VAR;
@@ -7702,81 +7522,6 @@ zend_accessor_info *zend_get_accessor_info_from_function(const zend_function *fu
77027522
}
77037523
/* }}} */
77047524

7705-
zend_accessor_info *zend_get_accessor_from_init_static_method_call(zend_op_array *op_array, zend_op *opline, const char **context_name_out TSRMLS_DC) /* {{{ */
7706-
{
7707-
zval *op1zv=NULL, *op2zv=NULL;
7708-
7709-
/* Unsure if we can rely on .zv to be resolved here already, normally resolved in pass_two on about line 597 */
7710-
if(!opline || !opline->opcode == ZEND_INIT_STATIC_METHOD_CALL) {
7711-
return NULL;
7712-
}
7713-
7714-
if (opline->op1_type == IS_CONST) {
7715-
if(opline->op2.constant < op_array->last_literal) { /* constant may already be translated to zv by pass_two() */
7716-
op1zv = &op_array->literals[opline->op1.constant].constant;
7717-
} else {
7718-
op1zv = opline->op1.zv;
7719-
}
7720-
}
7721-
if (opline->op2_type == IS_CONST) {
7722-
if(opline->op2.constant < op_array->last_literal) { /* constant may already be translated to zv by pass_two() */
7723-
op2zv = &op_array->literals[opline->op2.constant].constant;
7724-
} else {
7725-
op2zv = opline->op2.zv;
7726-
}
7727-
} else {
7728-
/* we only handle cases where op2_type == IS_CONST */
7729-
return NULL;
7730-
}
7731-
7732-
7733-
if(op2zv->type == IS_STRING && (memcmp(Z_STRVAL_P(op2zv),"__get", 5) == 0 || memcmp(Z_STRVAL_P(op2zv),"__set", 5) == 0)) {
7734-
zend_class_entry **classpp = NULL;
7735-
7736-
if(opline->op1_type == IS_CONST) {
7737-
char *lcname = zend_str_tolower_dup(Z_STRVAL_P(op1zv), Z_STRLEN_P(op1zv));
7738-
7739-
if(zend_hash_find(CG(class_table), lcname, Z_STRLEN_P(op1zv)+1, (void**)&classpp) == SUCCESS) {
7740-
*context_name_out = (const char*)(*classpp)->name;
7741-
}
7742-
7743-
efree(lcname);
7744-
} else if(opline->op1_type == IS_VAR) {
7745-
switch(opline->extended_value) {
7746-
case ZEND_FETCH_CLASS_SELF:
7747-
if(!CG(active_class_entry)) {
7748-
zend_error_noreturn(E_ERROR, "Cannot access self:: when no class scope is active");
7749-
}
7750-
*context_name_out = "self";
7751-
classpp = &CG(active_class_entry);
7752-
break;
7753-
case ZEND_FETCH_CLASS_PARENT:
7754-
if(!CG(active_class_entry)) {
7755-
zend_error_noreturn(E_ERROR, "Cannot access parent:: when no class scope is active");
7756-
}
7757-
if(!CG(active_class_entry)->parent) {
7758-
zend_error_noreturn(E_ERROR, "Cannot access parent::%s, %s has no parent class.", Z_STRVAL_P(op2zv)+5, CG(active_class_entry)->name);
7759-
}
7760-
*context_name_out = "parent";
7761-
classpp = &CG(active_class_entry)->parent;
7762-
break;
7763-
}
7764-
}
7765-
if(classpp) {
7766-
zend_property_info *property_info;
7767-
char *lcname2 = zend_str_tolower_dup(Z_STRVAL_P(op2zv)+5, Z_STRLEN_P(op2zv)-5); /* strlen("__get") == 5 */
7768-
7769-
if(zend_hash_find(&(*classpp)->properties_info, lcname2, Z_STRLEN_P(op2zv)-4, (void**)&property_info) == SUCCESS) {
7770-
efree(lcname2);
7771-
return property_info->ai;
7772-
}
7773-
efree(lcname2);
7774-
}
7775-
}
7776-
return NULL;
7777-
}
7778-
/* }}} */
7779-
77807525
/* {{{ zend_dirname
77817526
Returns directory name component of path */
77827527
ZEND_API size_t zend_dirname(char *path, size_t len)

Zend/zend_opcode.c

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -651,9 +651,6 @@ static void zend_resolve_finally_calls(zend_op_array *op_array TSRMLS_DC)
651651
ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
652652
{
653653
zend_op *opline, *end;
654-
zend_bool original_in_compilation = CG(in_compilation);
655-
char *original_compiled_filename = CG(compiled_filename);
656-
int original_zend_lineno = CG(zend_lineno);
657654

658655
if( (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) ) {
659656
return 0;
@@ -684,13 +681,9 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
684681
CG(context).literals_size = op_array->last_literal;
685682
}
686683

687-
CG(in_compilation) = 1;
688-
CG(compiled_filename) = (char*)op_array->filename;
689-
690684
opline = op_array->opcodes;
691685
end = opline + op_array->last;
692686
while (opline < end) {
693-
CG(zend_lineno) = opline->lineno;
694687
if (opline->op1_type == IS_CONST) {
695688
opline->op1.zv = &op_array->literals[opline->op1.constant].constant;
696689
}
@@ -726,39 +719,15 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
726719
opline->opcode = ZEND_GENERATOR_RETURN;
727720
}
728721
break;
729-
case ZEND_INIT_STATIC_METHOD_CALL: {
730-
/** Is this a call to a static getter, static setters are dependent on static getters (which get backpatched to setter calls), so during compilation
731-
* a static getter call may be in the op_array and if no zend_do_assign() has been called to backpatch it, then it's an illegal getter call, this
732-
* checks to see that by this point any getter that has not been backpatched, actually exists as a getter, or errors. */
733-
const char *context_name; /* Does not need to be free'd */
734-
735-
zend_accessor_info *ai = zend_get_accessor_from_init_static_method_call(op_array, opline, &context_name TSRMLS_CC);
736-
if(ai) {
737-
if(Z_STRVAL_P(opline->op2.zv)[2] == 'g') {
738-
if(!ai->getter) {
739-
zend_error_noreturn(E_ERROR, "Cannot get property %s::$%s, no getter defined.", context_name, Z_STRVAL_P(opline->op2.zv)+5);
740-
}
741-
} else if (Z_STRVAL_P(opline->op2.zv)[2] == 's') {
742-
if(!ai->setter) {
743-
zend_error_noreturn(E_ERROR, "Cannot set property %s::$%s, no setter defined.", context_name, Z_STRVAL_P(opline->op2.zv)+5);
744-
}
745-
}
746-
}
747-
}
748-
break;
749722
}
750723
ZEND_VM_SET_OPCODE_HANDLER(opline);
751724
opline++;
752725
}
753726

754727
op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO;
755-
CG(in_compilation) = original_in_compilation;
756-
CG(compiled_filename) = original_compiled_filename;
757-
CG(zend_lineno) = original_zend_lineno;
758728
return 0;
759729
}
760730

761-
762731
int print_class(zend_class_entry *class_entry TSRMLS_DC)
763732
{
764733
printf("Class %s:\n", class_entry->name);

0 commit comments

Comments
 (0)