Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 336e6e2

Browse files
committed
Add regression test for broken non commutative multiplication
1 parent 50bd8ba commit 336e6e2

File tree

4 files changed

+169
-1
lines changed

4 files changed

+169
-1
lines changed

‎ext/zend_test/test.c‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,73 @@ static ZEND_METHOD(ZendTestForbidDynamicCall, callStatic)
611611
zend_forbid_dynamic_call();
612612
}
613613

614+
// TODO HERE
615+
/* ncm refers to non commutative multiplication */
616+
static zend_class_entry *ncm_ce;
617+
static zend_object_handlers ncm_object_handlers;
618+
619+
static zend_object* ncm_object_create_ex(zend_class_entry* ce, zend_long l) {
620+
zend_object *obj = zend_objects_new(ce);
621+
object_properties_init(obj, ce);
622+
obj->handlers = &ncm_object_handlers;
623+
ZVAL_LONG(OBJ_PROP_NUM(obj, 0), l);
624+
return obj;
625+
}
626+
static zend_object *ncm_object_create(zend_class_entry *ce) /* {{{ */
627+
{
628+
return ncm_object_create_ex(ce, 0);
629+
}
630+
/* }}} */
631+
632+
static inline void ncm_create(zval *target, zend_long l) /* {{{ */
633+
{
634+
ZVAL_OBJ(target, ncm_object_create_ex(ncm_ce, l));
635+
}
636+
637+
#define IS_NCM(zval) \
638+
(Z_TYPE_P(zval) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zval), ncm_ce))
639+
640+
static void ncm_subtraction(zval *result, zval *op1, zval *op2)
641+
{
642+
zend_long val_1;
643+
zend_long val_2;
644+
if (IS_NCM(op1)) {
645+
val_1 = Z_LVAL_P(OBJ_PROP_NUM(Z_OBJ_P(op1), 0));
646+
} else {
647+
val_1 = zval_get_long(op1);
648+
}
649+
if (IS_NCM(op2)) {
650+
val_2 = Z_LVAL_P(OBJ_PROP_NUM(Z_OBJ_P(op2), 0));
651+
} else {
652+
val_2 = zval_get_long(op2);
653+
}
654+
655+
ncm_create(result, val_1 - val_2);
656+
}
657+
658+
static zend_result ncm_do_operation(zend_uchar opcode, zval *result, zval *op1, zval *op2)
659+
{
660+
switch (opcode) {
661+
case ZEND_MUL:
662+
ncm_subtraction(result, op1, op2);
663+
if (UNEXPECTED(EG(exception))) { return FAILURE; }
664+
return SUCCESS;
665+
default:
666+
return FAILURE;
667+
}
668+
}
669+
670+
PHP_METHOD(NonCommutativeMultiplication, __construct)
671+
{
672+
zend_long l;
673+
674+
ZEND_PARSE_PARAMETERS_START(1, 1)
675+
Z_PARAM_LONG(l)
676+
ZEND_PARSE_PARAMETERS_END();
677+
678+
ZVAL_LONG(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), l);
679+
}
680+
614681
PHP_INI_BEGIN()
615682
STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals)
616683
STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
@@ -713,6 +780,12 @@ PHP_MINIT_FUNCTION(zend_test)
713780
zend_test_string_enum = register_class_ZendTestStringEnum();
714781
zend_test_int_enum = register_class_ZendTestIntEnum();
715782

783+
/* Non commutative multiplication class */
784+
ncm_ce = register_class_NonCommutativeMultiplication();
785+
ncm_ce->create_object = ncm_object_create;
786+
memcpy(&ncm_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
787+
ncm_object_handlers.do_operation = ncm_do_operation;
788+
716789
zend_register_functions(NULL, ext_function_legacy, NULL, EG(current_module)->type);
717790

718791
// Loading via dl() not supported with the observer API

‎ext/zend_test/test.stub.php‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ enum ZendTestIntEnum: int {
9898
case Baz = -1;
9999
}
100100

101+
final class NonCommutativeMultiplication {
102+
private int $val;
103+
104+
public function __construct(int $val) {}
105+
}
106+
101107
function zend_test_array_return(): array {}
102108

103109
function zend_test_nullable_array_return(): ?array {}

‎ext/zend_test/test_arginfo.h‎

Lines changed: 29 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
--TEST--
2+
Zend: test non commutative multiplication object handler
3+
--EXTENSIONS--
4+
zend_test
5+
--XFAIL--
6+
Broken non commutative multiplication with more than 2 ops
7+
--FILE--
8+
<?php
9+
10+
$ten = new NonCommutativeMultiplication(10);
11+
$fifty = new NonCommutativeMultiplication(50);
12+
$hundred = new NonCommutativeMultiplication(100);
13+
14+
var_dump($ten);
15+
var_dump($fifty);
16+
var_dump($hundred);
17+
18+
/* $hundred * 20 gives a new NCM object, thus final result is 30 = ((100 - 20) - 50) */
19+
var_dump($hundred * 20 * 50);
20+
/* Multiplication corresponds to subtraction for this object */
21+
var_dump(100 - 50 - 10);
22+
var_dump($hundred * $fifty * $ten);
23+
var_dump(10 - 50 - 100);
24+
var_dump($ten * $fifty * $hundred);
25+
var_dump(50 - 100 - 10);
26+
var_dump($fifty * $hundred * $ten);
27+
28+
29+
?>
30+
--EXPECT--
31+
object(NonCommutativeMultiplication)#1 (1) {
32+
["val":"NonCommutativeMultiplication":private]=>
33+
int(10)
34+
}
35+
object(NonCommutativeMultiplication)#2 (1) {
36+
["val":"NonCommutativeMultiplication":private]=>
37+
int(50)
38+
}
39+
object(NonCommutativeMultiplication)#3 (1) {
40+
["val":"NonCommutativeMultiplication":private]=>
41+
int(100)
42+
}
43+
object(NonCommutativeMultiplication)#5 (1) {
44+
["val":"NonCommutativeMultiplication":private]=>
45+
int(30)
46+
}
47+
int(40)
48+
object(NonCommutativeMultiplication)#4 (1) {
49+
["val":"NonCommutativeMultiplication":private]=>
50+
int(40)
51+
}
52+
int(-140)
53+
object(NonCommutativeMultiplication)#5 (1) {
54+
["val":"NonCommutativeMultiplication":private]=>
55+
int(-140)
56+
}
57+
int(-60)
58+
object(NonCommutativeMultiplication)#4 (1) {
59+
["val":"NonCommutativeMultiplication":private]=>
60+
int(-60)
61+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /