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);
+
+}
