summaryrefslogtreecommitdiff
path: root/devel/pecl-vld/files/patch-php84
blob: 96c47096e8c6f1bae07f6ddf42985b6c56ad6d13 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
Obtained from:	https://github.com/derickr/vld/commit/df1c52c4cb62e5ff31e1b72e3f11df9a45ee567a
		https://github.com/derickr/vld/commit/dc56f73a25b0230745afb5523871f2e8dd33fccd

--- srm_oparray.c.orig	2022-09-16 08:00:47 UTC
+++ srm_oparray.c
@@ -350,6 +350,16 @@ static const op_usage opcodes[] = {
 	/*  200 */	{ "FETCH_GLOBALS", ALL_USED },
 	/*  201 */	{ "VERIFY_NEVER_TYPE", ALL_USED },
 	/*  202 */	{ "ZEND_CALLABLE_CONVERT", ALL_USED },
+#    if PHP_VERSION_ID >= 80300
+	/*  203 */  { "ZEND_BIND_INIT_STATIC_OR_JMP", ALL_USED },
+#     if PHP_VERSION_ID >= 80400
+	/*  204 */  { "ZEND_FRAMELESS_ICALL_0", ALL_USED | EXT_VAL_FLF },
+	/*  205 */  { "ZEND_FRAMELESS_ICALL_1", ALL_USED | EXT_VAL_FLF },
+	/*  206 */  { "ZEND_FRAMELESS_ICALL_2", ALL_USED | EXT_VAL_FLF },
+	/*  207 */  { "ZEND_FRAMELESS_ICALL_3", ALL_USED | EXT_VAL_FLF },
+	/*  208 */  { "ZEND_JMP_FRAMELESS", ALL_USED | EXT_CACHED_PTR | OP2_OPNUM },
+#     endif
+#    endif
 #   endif
 #  endif
 # else
@@ -811,6 +821,12 @@ void vld_dump_op(int nr, zend_op * op_ptr, unsigned in
 		last_lineno = op.lineno;
 	}
 
+#if PHP_VERSION_ID >= 80400
+	if (flags & EXT_VAL_FLF) {
+		fetch_type = (char*) ZEND_FLF_FUNC(&op)->common.function_name->val;
+	}
+#endif
+
 	if (op.opcode >= NUM_KNOWN_OPCODES) {
 		if (VLD_G(format)) {
 			vld_printf(stderr, "%5d %s %c %c %c %c %s <%03d>%-23s %s %-14s ", nr, VLD_G(col_sep), notdead ? ' ' : '*', entry ? 'E' : ' ', start ? '>' : ' ', end ? '>' : ' ', VLD_G(col_sep), op.opcode, VLD_G(col_sep), fetch_type);
@@ -831,6 +847,11 @@ void vld_dump_op(int nr, zend_op * op_ptr, unsigned in
 		}
 	}
 
+#if PHP_VERSION_ID >= 80400
+	if (flags & EXT_CACHED_PTR) {
+		vld_printf(stderr, "s%-3d ", op.extended_value);
+	} else
+#endif
 	if (flags & EXT_VAL) {
 #if PHP_VERSION_ID >= 70300
 		if (op.opcode == ZEND_CATCH) {
@@ -1082,9 +1103,19 @@ int vld_find_jumps(zend_op_array *opa, unsigned int po
 		*jump_count = 1;
 		return 1;
 
+#if PHP_VERSION_ID >= 80400
+	} else if (opcode.opcode == ZEND_JMP_FRAMELESS) {
+		jumps[0] = position + 1;
+		jumps[1] = VLD_ZNODE_JMP_LINE(opcode.op2, position, base_address);
+		*jump_count = 2;
+		return 1;
+#endif
+
 	} else if (
 		opcode.opcode == ZEND_GENERATOR_RETURN ||
+#if PHP_VERSION_ID < 80400
 		opcode.opcode == ZEND_EXIT ||
+#endif
 		opcode.opcode == ZEND_THROW ||
 #if PHP_VERSION_ID >= 80000
 		opcode.opcode == ZEND_MATCH_ERROR ||
@@ -1094,6 +1125,49 @@ int vld_find_jumps(zend_op_array *opa, unsigned int po
 		jumps[0] = VLD_JMP_EXIT;
 		*jump_count = 1;
 		return 1;
+#if PHP_VERSION_ID >= 80200
+	} else if (
+		opcode.opcode == ZEND_INIT_FCALL
+	) {
+		zval *func_name = RT_CONSTANT(&opa->opcodes[position], opcode.op2);
+		if (zend_string_equals_literal(Z_PTR_P(func_name), "exit")) {
+			int level = 0;
+			uint32_t start = position + 1;
+
+			for (;;) {
+				switch (opa->opcodes[start].opcode) {
+					case ZEND_INIT_FCALL:
+					case ZEND_INIT_FCALL_BY_NAME:
+					case ZEND_INIT_NS_FCALL_BY_NAME:
+					case ZEND_INIT_DYNAMIC_CALL:
+					case ZEND_INIT_USER_CALL:
+					case ZEND_INIT_METHOD_CALL:
+					case ZEND_INIT_STATIC_METHOD_CALL:
+#if PHP_VERSION_ID >= 80400
+					case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
+#endif
+					case ZEND_NEW:
+						level++;
+						break;
+					case ZEND_DO_FCALL:
+					case ZEND_DO_FCALL_BY_NAME:
+					case ZEND_DO_ICALL:
+					case ZEND_DO_UCALL:
+						if (level == 0) {
+							goto done;
+						}
+						level--;
+						break;
+				}
+				start++;
+			}
+ done:
+			ZEND_ASSERT(opa->opcodes[start].opcode == ZEND_DO_ICALL);
+			jumps[0] = VLD_JMP_EXIT;
+			*jump_count = 1;
+			return 1;
+		}
+# endif
 #if PHP_VERSION_ID >= 70200
 	} else if (
 # if PHP_VERSION_ID >= 80000
@@ -1233,6 +1307,7 @@ void vld_analyse_branch(zend_op_array *opa, unsigned i
 			break;
 		}
 
+#if PHP_VERSION_ID < 80400
 		/* See if we have an exit instruction */
 		if (opa->opcodes[position].opcode == ZEND_EXIT) {
 			VLD_PRINT(1, "Exit found\n");
@@ -1240,6 +1315,7 @@ void vld_analyse_branch(zend_op_array *opa, unsigned i
 			branch_info->branches[position].start_lineno = opa->opcodes[position].lineno;
 			break;
 		}
+#endif
 		/* See if we have a return instruction */
 		if (
 			opa->opcodes[position].opcode == ZEND_RETURN
--- srm_oparray.h.orig	2022-09-16 08:00:47 UTC
+++ srm_oparray.h
@@ -57,6 +57,8 @@
 #define EXT_VAL_JMP_ABS   1<<25
 #define VLD_IS_JMP_ARRAY  1<<26
 #define VLD_IS_INDEX      1<<27
+#define EXT_VAL_FLF       1<<28
+#define EXT_CACHED_PTR    1<<29
 
 typedef struct _op_usage {
 	const char  *name;
--- tests/jmp_frameless.inc.orig	2024-07-29 13:37:33 UTC
+++ tests/jmp_frameless.inc
@@ -0,0 +1,6 @@
+<?php
+namespace Foo {
+
+echo substr("Derick Cool?", 7);
+
+}