Long awaited line directive
| From: | Marcus Boerger | Date: | Sat, 15 Jul 2006 18:26:22 +0000 |
| Subject: | Long awaited line directive | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-24402@lists.php.net to get a copy of this message | ||
Hello internals,
attached is a patch that brings the '#line' directive to php.
This is especially usefull for parser generators or any other
code shuffling/generator tools. Any opinions? If nothing speaks
against i'd like to commit this before heading towards OSCON
be end of next week. (oatch is against head of course).
--
Best regards,
Marcus mailto:mail@marcus-boerger.de
Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.717 diff -u -p -d -r1.717 zend_compile.c --- Zend/zend_compile.c 13 Jun 2006 12:56:20 -0000 1.717 +++ Zend/zend_compile.c 15 Jul 2006 18:20:03 -0000 @@ -208,6 +208,23 @@ ZEND_API char *zend_set_compiled_filenam } +ZEND_API void zend_do_line_directive(long lineno, char *file, int file_len TSRMLS_DC) +{ + zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + + CG(zend_lineno) = lineno; + file = estrndup(file, file_len); + zend_set_compiled_filename(file TSRMLS_CC); + + opline->opcode = ZEND_LINE_DIRECTIVE; + SET_UNUSED(opline->result); + opline->op1.op_type = IS_CONST; + ZVAL_LONG(&opline->op1.u.constant, lineno); + opline->op2.op_type = IS_CONST; + ZVAL_STRINGL(&opline->op2.u.constant, file, file_len, 0); +} + + ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC) { CG(compiled_filename) = original_compiled_filename; Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.343 diff -u -p -d -r1.343 zend_compile.h --- Zend/zend_compile.h 13 Jun 2006 12:56:20 -0000 1.343 +++ Zend/zend_compile.h 15 Jul 2006 18:20:03 -0000 @@ -332,6 +332,7 @@ ZEND_API int lex_scan(zval *zendlval TSR void startup_scanner(TSRMLS_D); void shutdown_scanner(TSRMLS_D); +ZEND_API void zend_do_line_directive(long lineno, char *file, int file_len TSRMLS_DC); ZEND_API char *zend_set_compiled_filename(char *new_compiled_filename TSRMLS_DC); ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC); ZEND_API char *zend_get_compiled_filename(TSRMLS_D); Index: Zend/zend_language_scanner.l =================================================================== RCS file: /repository/ZendEngine2/zend_language_scanner.l,v retrieving revision 1.155 diff -u -p -d -r1.155 zend_language_scanner.l --- Zend/zend_language_scanner.l 12 Jun 2006 17:06:39 -0000 1.155 +++ Zend/zend_language_scanner.l 15 Jul 2006 18:20:04 -0000 @@ -1396,6 +1396,7 @@ EXPONENT_DNUM (({LNUM}|{DNUM})[eE][+-]?{ HNUM "0x"[0-9a-fA-F]+ LABEL [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* WHITESPACE [ \n\r\t]+ +WSONLY [ \t]+ TABS_AND_SPACES [ \t]* TOKENS [;:,.\[\]()|^&+-/*=%!~$<>?@] ENCAPSED_TOKENS [\[\]{}$] @@ -2099,6 +2100,28 @@ NEWLINE ("\r"|"\n"|"\r\n") } +<ST_IN_SCRIPTING>"#"{WSONLY}*"line"{WSONLY}{LNUM}{WSONLY}["][^"\r\n]*["]{NEWLINE} { +/* " */ + char *s, *e; + long l; + + errno = 0; + s = strchr(yytext, 'e') + 1; + l = strtol(s, &e, 0); + if (errno == ERANGE) { /* overflow */ + zend_error(E_COMPILE_ERROR, "#line directive invalid"); + } + s = strchr(e + 1, '"') + 1; + e = strrchr(s, '"'); + zend_do_line_directive(l, s, e - s TSRMLS_CC); + Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */ + Z_STRLEN_P(zendlval) = yyleng; + Z_TYPE_P(zendlval) = IS_STRING; + BEGIN(ST_IN_SCRIPTING); + return T_COMMENT; +} + + <ST_IN_SCRIPTING>"#"|"//" { BEGIN(ST_ONE_LINE_COMMENT); yymore(); Index: Zend/zend_vm_def.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_def.h,v retrieving revision 1.125 diff -u -p -d -r1.125 zend_vm_def.h --- Zend/zend_vm_def.h 12 Jul 2006 21:14:11 -0000 1.125 +++ Zend/zend_vm_def.h 15 Jul 2006 18:20:05 -0000 @@ -3893,4 +3893,18 @@ ZEND_VM_HANDLER(151, ZEND_U_NORMALIZE, C ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HANDLER(152, ZEND_LINE_DIRECTIVE, CONST, ANY) +{ + zend_op *opline = EX(opline); + zend_free_op free_op1, free_op2; + /*zval *line = GET_OP1_ZVAL_PTR(BP_VAR_R);*/ + zval *file = GET_OP2_ZVAL_PTR(BP_VAR_R); + + zend_set_compiled_filename(Z_STRVAL_P(file) TSRMLS_CC); + + FREE_OP1_IF_VAR(); + FREE_OP2_IF_VAR(); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper) Index: Zend/zend_vm_execute.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_execute.h,v retrieving revision 1.129 diff -u -p -d -r1.129 zend_vm_execute.h --- Zend/zend_vm_execute.h 12 Jul 2006 21:14:11 -0000 1.129 +++ Zend/zend_vm_execute.h 15 Jul 2006 18:20:10 -0000 @@ -2334,6 +2334,19 @@ static int ZEND_U_NORMALIZE_SPEC_CONST_H ZEND_VM_NEXT_OPCODE(); } +static int ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_op *opline = EX(opline); + zend_free_op free_op2; + /*zval *line = &opline->op1.u.constant;*/ + zval *file = get_zval_ptr(&opline->op2, EX(Ts), &free_op2, BP_VAR_R); + + zend_set_compiled_filename(Z_STRVAL_P(file) TSRMLS_CC); + + FREE_OP_IF_VAR(free_op2); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -31093,6 +31106,31 @@ void zend_init_opcodes_handlers() ZEND_U_NORMALIZE_SPEC_CV_HANDLER, ZEND_U_NORMALIZE_SPEC_CV_HANDLER, ZEND_U_NORMALIZE_SPEC_CV_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = (opcode_handler_t*)labels; Index: Zend/zend_vm_opcodes.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_opcodes.h,v retrieving revision 1.67 diff -u -p -d -r1.67 zend_vm_opcodes.h --- Zend/zend_vm_opcodes.h 10 Mar 2006 08:29:22 -0000 1.67 +++ Zend/zend_vm_opcodes.h 15 Jul 2006 18:20:10 -0000 @@ -149,3 +149,4 @@ #define ZEND_HANDLE_EXCEPTION 149 #define ZEND_USER_OPCODE 150 #define ZEND_U_NORMALIZE 151 +#define ZEND_LINE_DIRECTIVE 152
Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.717 diff -u -p -d -r1.717 zend_compile.c --- Zend/zend_compile.c 13 Jun 2006 12:56:20 -0000 1.717 +++ Zend/zend_compile.c 15 Jul 2006 18:20:03 -0000 @@ -208,6 +208,23 @@ ZEND_API char *zend_set_compiled_filenam } +ZEND_API void zend_do_line_directive(long lineno, char *file, int file_len TSRMLS_DC) +{ + zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + + CG(zend_lineno) = lineno; + file = estrndup(file, file_len); + zend_set_compiled_filename(file TSRMLS_CC); + + opline->opcode = ZEND_LINE_DIRECTIVE; + SET_UNUSED(opline->result); + opline->op1.op_type = IS_CONST; + ZVAL_LONG(&opline->op1.u.constant, lineno); + opline->op2.op_type = IS_CONST; + ZVAL_STRINGL(&opline->op2.u.constant, file, file_len, 0); +} + + ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC) { CG(compiled_filename) = original_compiled_filename; Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.343 diff -u -p -d -r1.343 zend_compile.h --- Zend/zend_compile.h 13 Jun 2006 12:56:20 -0000 1.343 +++ Zend/zend_compile.h 15 Jul 2006 18:20:03 -0000 @@ -332,6 +332,7 @@ ZEND_API int lex_scan(zval *zendlval TSR void startup_scanner(TSRMLS_D); void shutdown_scanner(TSRMLS_D); +ZEND_API void zend_do_line_directive(long lineno, char *file, int file_len TSRMLS_DC); ZEND_API char *zend_set_compiled_filename(char *new_compiled_filename TSRMLS_DC); ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC); ZEND_API char *zend_get_compiled_filename(TSRMLS_D); Index: Zend/zend_language_scanner.l =================================================================== RCS file: /repository/ZendEngine2/zend_language_scanner.l,v retrieving revision 1.155 diff -u -p -d -r1.155 zend_language_scanner.l --- Zend/zend_language_scanner.l 12 Jun 2006 17:06:39 -0000 1.155 +++ Zend/zend_language_scanner.l 15 Jul 2006 18:20:04 -0000 @@ -1396,6 +1396,7 @@ EXPONENT_DNUM (({LNUM}|{DNUM})[eE][+-]?{ HNUM "0x"[0-9a-fA-F]+ LABEL [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* WHITESPACE [ \n\r\t]+ +WSONLY [ \t]+ TABS_AND_SPACES [ \t]* TOKENS [;:,.\[\]()|^&+-/*=%!~$<>?@] ENCAPSED_TOKENS [\[\]{}$] @@ -2099,6 +2100,28 @@ NEWLINE ("\r"|"\n"|"\r\n") } +<ST_IN_SCRIPTING>"#"{WSONLY}*"line"{WSONLY}{LNUM}{WSONLY}["][^"\r\n]*["]{NEWLINE} { +/* " */ + char *s, *e; + long l; + + errno = 0; + s = strchr(yytext, 'e') + 1; + l = strtol(s, &e, 0); + if (errno == ERANGE) { /* overflow */ + zend_error(E_COMPILE_ERROR, "#line directive invalid"); + } + s = strchr(e + 1, '"') + 1; + e = strrchr(s, '"'); + zend_do_line_directive(l, s, e - s TSRMLS_CC); + Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */ + Z_STRLEN_P(zendlval) = yyleng; + Z_TYPE_P(zendlval) = IS_STRING; + BEGIN(ST_IN_SCRIPTING); + return T_COMMENT; +} + + <ST_IN_SCRIPTING>"#"|"//" { BEGIN(ST_ONE_LINE_COMMENT); yymore(); Index: Zend/zend_vm_def.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_def.h,v retrieving revision 1.125 diff -u -p -d -r1.125 zend_vm_def.h --- Zend/zend_vm_def.h 12 Jul 2006 21:14:11 -0000 1.125 +++ Zend/zend_vm_def.h 15 Jul 2006 18:20:05 -0000 @@ -3893,4 +3893,18 @@ ZEND_VM_HANDLER(151, ZEND_U_NORMALIZE, C ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HANDLER(152, ZEND_LINE_DIRECTIVE, CONST, ANY) +{ + zend_op *opline = EX(opline); + zend_free_op free_op1, free_op2; + /*zval *line = GET_OP1_ZVAL_PTR(BP_VAR_R);*/ + zval *file = GET_OP2_ZVAL_PTR(BP_VAR_R); + + zend_set_compiled_filename(Z_STRVAL_P(file) TSRMLS_CC); + + FREE_OP1_IF_VAR(); + FREE_OP2_IF_VAR(); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper) Index: Zend/zend_vm_execute.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_execute.h,v retrieving revision 1.129 diff -u -p -d -r1.129 zend_vm_execute.h --- Zend/zend_vm_execute.h 12 Jul 2006 21:14:11 -0000 1.129 +++ Zend/zend_vm_execute.h 15 Jul 2006 18:20:10 -0000 @@ -2334,6 +2334,19 @@ static int ZEND_U_NORMALIZE_SPEC_CONST_H ZEND_VM_NEXT_OPCODE(); } +static int ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_op *opline = EX(opline); + zend_free_op free_op2; + /*zval *line = &opline->op1.u.constant;*/ + zval *file = get_zval_ptr(&opline->op2, EX(Ts), &free_op2, BP_VAR_R); + + zend_set_compiled_filename(Z_STRVAL_P(file) TSRMLS_CC); + + FREE_OP_IF_VAR(free_op2); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_ADD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -31093,6 +31106,31 @@ void zend_init_opcodes_handlers() ZEND_U_NORMALIZE_SPEC_CV_HANDLER, ZEND_U_NORMALIZE_SPEC_CV_HANDLER, ZEND_U_NORMALIZE_SPEC_CV_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_LINE_DIRECTIVE_SPEC_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = (opcode_handler_t*)labels; Index: Zend/zend_vm_opcodes.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_opcodes.h,v retrieving revision 1.67 diff -u -p -d -r1.67 zend_vm_opcodes.h --- Zend/zend_vm_opcodes.h 10 Mar 2006 08:29:22 -0000 1.67 +++ Zend/zend_vm_opcodes.h 15 Jul 2006 18:20:10 -0000 @@ -149,3 +149,4 @@ #define ZEND_HANDLE_EXCEPTION 149 #define ZEND_USER_OPCODE 150 #define ZEND_U_NORMALIZE 151 +#define ZEND_LINE_DIRECTIVE 152