Skip to content

Commit 4d4a5ab

Browse files
iluuu1994nikic
andcommitted
Accessors implementation
Co-authored-by: Nikita Popov <[email protected]>
1 parent e8fb0ed commit 4d4a5ab

File tree

181 files changed

+6720
-1003
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+6720
-1003
lines changed

Zend/Optimizer/compact_literals.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
197197
LITERAL_INFO(opline->op2.constant, 2);
198198
}
199199
break;
200+
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
201+
LITERAL_INFO(opline->op1.constant, 1);
202+
break;
200203
case ZEND_CATCH:
201204
LITERAL_INFO(opline->op1.constant, 2);
202205
break;

Zend/Optimizer/optimize_func_calls.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opli
4747
case ZEND_INIT_STATIC_METHOD_CALL:
4848
case ZEND_INIT_METHOD_CALL:
4949
case ZEND_INIT_FCALL:
50+
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
5051
if (call == 0) {
5152
MAKE_NOP(opline);
5253
return;
@@ -95,6 +96,11 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o
9596
return;
9697
}
9798

99+
if (fcall->opcode == ZEND_INIT_PARENT_PROPERTY_HOOK_CALL) {
100+
/* Don't inline property hook method */
101+
return;
102+
}
103+
98104
for (i = 0; i < num_args; i++) {
99105
/* Don't inline functions with by-reference arguments. This would require
100106
* correct handling of INDIRECT arguments. */
@@ -168,6 +174,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
168174
case ZEND_INIT_METHOD_CALL:
169175
case ZEND_INIT_FCALL:
170176
case ZEND_NEW:
177+
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
171178
/* The argument passing optimizations are valid for prototypes as well,
172179
* as inheritance cannot change between ref <-> non-ref arguments. */
173180
call_stack[call].func = zend_optimizer_get_called_func(
@@ -211,6 +218,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
211218
}
212219
} else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL
213220
|| fcall->opcode == ZEND_INIT_METHOD_CALL
221+
|| fcall->opcode == ZEND_INIT_PARENT_PROPERTY_HOOK_CALL
214222
|| fcall->opcode == ZEND_NEW) {
215223
/* We don't have specialized opcodes for this, do nothing */
216224
} else {

Zend/Optimizer/zend_call_graph.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
6161
case ZEND_INIT_FCALL:
6262
case ZEND_INIT_METHOD_CALL:
6363
case ZEND_INIT_STATIC_METHOD_CALL:
64+
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
6465
call_stack[call] = call_info;
6566
func = zend_optimizer_get_called_func(
6667
script, op_array, opline, &is_prototype);

Zend/Optimizer/zend_optimizer.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,27 @@ zend_function *zend_optimizer_get_called_func(
910910
}
911911
}
912912
break;
913+
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:;
914+
zend_class_entry *scope = op_array->scope;
915+
ZEND_ASSERT(scope != NULL);
916+
if (scope && (scope->ce_flags & ZEND_ACC_LINKED) && scope->parent) {
917+
zend_class_entry *parent_scope = scope->parent;
918+
zend_string *prop_name = Z_STR_P(CRT_CONSTANT(opline->op1));
919+
zend_property_hook_kind hook_kind = opline->op2.num;
920+
zend_property_info *prop_info = zend_get_property_info(parent_scope, prop_name, /* silent */ true);
921+
922+
if (prop_info
923+
&& prop_info != ZEND_WRONG_PROPERTY_INFO
924+
&& !(prop_info->flags & ZEND_ACC_PRIVATE)
925+
&& prop_info->hooks) {
926+
zend_function *fbc = prop_info->hooks[hook_kind];
927+
if (fbc) {
928+
*is_prototype = true;
929+
return fbc;
930+
}
931+
}
932+
}
933+
break;
913934
case ZEND_NEW:
914935
{
915936
zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
@@ -1425,6 +1446,7 @@ void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void
14251446
{
14261447
zval *zv;
14271448
zend_op_array *op_array;
1449+
zend_property_info *property;
14281450

14291451
zend_foreach_op_array_helper(&script->main_op_array, func, context);
14301452

@@ -1445,6 +1467,17 @@ void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void
14451467
zend_foreach_op_array_helper(op_array, func, context);
14461468
}
14471469
} ZEND_HASH_FOREACH_END();
1470+
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, property) {
1471+
zend_function **hooks = property->hooks;
1472+
if (hooks) {
1473+
for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
1474+
zend_function *hook = hooks[i];
1475+
if (hook && hook->common.scope == ce) {
1476+
zend_foreach_op_array_helper(&hooks[i]->op_array, func, context);
1477+
}
1478+
}
1479+
}
1480+
} ZEND_HASH_FOREACH_END();
14481481
} ZEND_HASH_FOREACH_END();
14491482
}
14501483

Zend/tests/accessors/final.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Final accessors
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public $prop {
8+
final get { return 42; }
9+
}
10+
}
11+
12+
class B extends A {
13+
public $prop {
14+
get { return 24; }
15+
}
16+
}
17+
18+
?>
19+
--EXPECTF--
20+
Fatal error: Cannot override final accessor A::$prop::get() in %s on line %d

Zend/tests/alternative_offset_syntax_compile_error_in_const_expr.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ const FOO_COMPILE_ERROR = "BAR"{0};
66
var_dump(FOO_COMPILE_ERROR);
77
?>
88
--EXPECTF--
9-
Fatal error: Array and string offset access syntax with curly braces is no longer supported in %s on line 2
9+
Parse error: syntax error, unexpected token "{", expecting "," or ";" in %s on line %d

Zend/tests/alternative_offset_syntax_compile_error_outside_const_expr.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ $foo = 'BAR';
66
var_dump($foo{0});
77
?>
88
--EXPECTF--
9-
Fatal error: Array and string offset access syntax with curly braces is no longer supported in %s on line 3
9+
Parse error: syntax error, unexpected token "{", expecting ")" in %s on line %d

Zend/tests/alternative_offset_syntax_in_encaps_string.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ Alternative offset syntax should emit only E_COMPILE_ERROR in string interpolati
33
--FILE--
44
<?php "{$g{'h'}}"; ?>
55
--EXPECTF--
6-
Fatal error: Array and string offset access syntax with curly braces is no longer supported in %s on line 1
6+
Parse error: syntax error, unexpected token "{", expecting "->" or "?->" or "[" in %s on line %d

Zend/tests/errmsg_037.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ class test {
1010
echo "Done\n";
1111
?>
1212
--EXPECTF--
13-
Fatal error: Cannot use the abstract modifier on a property in %s on line %d
13+
Fatal error: Only hooked properties may be declared abstract in %s on line %d

Zend/tests/errmsg_038.phpt

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)