Skip to content

Commit 1d21222

Browse files
committed
zend_vm_gen: Track line numbers on a per-file basis
php#19789 fixed the line number references for `zend_vm_def.h`, when generating with line number information some of them are also specific to `zend_vm_execute.h` and thus should reference that file instead with the correct line numbers. The line number tracking was broken, because it was tracked in a single global variable, instead of being tracked on a per-file basis. Fix this by making the line numbers an array indexed by the resource ID and consistently using the `out()` functions to write into the files.
1 parent 51033c2 commit 1d21222

File tree

1 file changed

+48
-38
lines changed

1 file changed

+48
-38
lines changed

Zend/zend_vm_gen.php

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -545,21 +545,31 @@
545545
$helpers = array(); // opcode helpers by name
546546
$params = array(); // parameters of helpers
547547
$opnames = array(); // opcode name to code mapping
548-
$line_no = 1;
548+
$line_nos = [];
549549

550550
$used_extra_spec = array();
551551

552552
// Writes $s into resulting executor
553553
function out($f, $s) {
554-
global $line_no;
554+
global $line_nos;
555+
556+
$line_no = &$line_nos[(int)$f];
557+
if ($line_no === null) {
558+
$line_no = 1;
559+
}
555560

556561
fputs($f,$s);
557562
$line_no += substr_count($s, "\n");
558563
}
559564

560565
// Resets #line directives in resulting executor
561566
function out_line($f) {
562-
global $line_no, $executor_file;
567+
global $line_nos, $executor_file;
568+
569+
$line_no = &$line_nos[(int)$f];
570+
if ($line_no === null) {
571+
$line_no = 1;
572+
}
563573

564574
fputs($f,"#line ".($line_no+1)." \"".$executor_file."\"\n");
565575
++$line_no;
@@ -2839,46 +2849,46 @@ function gen_vm($def, $skel) {
28392849

28402850
// Insert header
28412851
out($f, HEADER_TEXT);
2842-
fputs($f,"#include <stdio.h>\n");
2843-
fputs($f,"#include <zend.h>\n");
2844-
fputs($f,"#include <zend_vm_opcodes.h>\n\n");
2852+
out($f,"#include <stdio.h>\n");
2853+
out($f,"#include <zend.h>\n");
2854+
out($f,"#include <zend_vm_opcodes.h>\n\n");
28452855

2846-
fputs($f,"static const char *zend_vm_opcodes_names[".($max_opcode + 1)."] = {\n");
2856+
out($f,"static const char *zend_vm_opcodes_names[".($max_opcode + 1)."] = {\n");
28472857
for ($i = 0; $i <= $max_opcode; $i++) {
2848-
fputs($f,"\t".(isset($opcodes[$i]["op"])?'"'.$opcodes[$i]["op"].'"':"NULL").",\n");
2858+
out($f,"\t".(isset($opcodes[$i]["op"])?'"'.$opcodes[$i]["op"].'"':"NULL").",\n");
28492859
}
2850-
fputs($f, "};\n\n");
2860+
out($f, "};\n\n");
28512861

2852-
fputs($f,"static uint32_t zend_vm_opcodes_flags[".($max_opcode + 1)."] = {\n");
2862+
out($f,"static uint32_t zend_vm_opcodes_flags[".($max_opcode + 1)."] = {\n");
28532863
for ($i = 0; $i <= $max_opcode; $i++) {
2854-
fprintf($f, "\t0x%08x,\n", isset($opcodes[$i]["flags"]) ? $opcodes[$i]["flags"] : 0);
2855-
}
2856-
fputs($f, "};\n\n");
2857-
2858-
fputs($f, "ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) {\n");
2859-
fputs($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
2860-
fputs($f, "\t\treturn NULL;\n");
2861-
fputs($f, "\t}\n");
2862-
fputs($f, "\treturn zend_vm_opcodes_names[opcode];\n");
2863-
fputs($f, "}\n");
2864-
2865-
fputs($f, "ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(uint8_t opcode) {\n");
2866-
fputs($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
2867-
fputs($f, "\t\topcode = ZEND_NOP;\n");
2868-
fputs($f, "\t}\n");
2869-
fputs($f, "\treturn zend_vm_opcodes_flags[opcode];\n");
2870-
fputs($f, "}\n");
2871-
2872-
fputs($f, "ZEND_API uint8_t zend_get_opcode_id(const char *name, size_t length) {\n");
2873-
fputs($f, "\tuint8_t opcode;\n");
2874-
fputs($f, "\tfor (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) {\n");
2875-
fputs($f, "\t\tconst char *opcode_name = zend_vm_opcodes_names[opcode];\n");
2876-
fputs($f, "\t\tif (opcode_name && strncmp(opcode_name, name, length) == 0) {\n");
2877-
fputs($f, "\t\t\treturn opcode;\n");
2878-
fputs($f, "\t\t}\n");
2879-
fputs($f, "\t}\n");
2880-
fputs($f, "\treturn ZEND_VM_LAST_OPCODE + 1;\n");
2881-
fputs($f, "}\n");
2864+
out($f, sprintf("\t0x%08x,\n", isset($opcodes[$i]["flags"]) ? $opcodes[$i]["flags"] : 0));
2865+
}
2866+
out($f, "};\n\n");
2867+
2868+
out($f, "ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) {\n");
2869+
out($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
2870+
out($f, "\t\treturn NULL;\n");
2871+
out($f, "\t}\n");
2872+
out($f, "\treturn zend_vm_opcodes_names[opcode];\n");
2873+
out($f, "}\n");
2874+
2875+
out($f, "ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(uint8_t opcode) {\n");
2876+
out($f, "\tif (UNEXPECTED(opcode > ZEND_VM_LAST_OPCODE)) {\n");
2877+
out($f, "\t\topcode = ZEND_NOP;\n");
2878+
out($f, "\t}\n");
2879+
out($f, "\treturn zend_vm_opcodes_flags[opcode];\n");
2880+
out($f, "}\n");
2881+
2882+
out($f, "ZEND_API uint8_t zend_get_opcode_id(const char *name, size_t length) {\n");
2883+
out($f, "\tuint8_t opcode;\n");
2884+
out($f, "\tfor (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) {\n");
2885+
out($f, "\t\tconst char *opcode_name = zend_vm_opcodes_names[opcode];\n");
2886+
out($f, "\t\tif (opcode_name && strncmp(opcode_name, name, length) == 0) {\n");
2887+
out($f, "\t\t\treturn opcode;\n");
2888+
out($f, "\t\t}\n");
2889+
out($f, "\t}\n");
2890+
out($f, "\treturn ZEND_VM_LAST_OPCODE + 1;\n");
2891+
out($f, "}\n");
28822892

28832893
fclose($f);
28842894
echo "zend_vm_opcodes.c generated successfully.\n";

0 commit comments

Comments
 (0)