]> granicus.if.org Git - php/commitdiff
Export zend_do_fcall() helper from executor
authorDmitry Stogov <dmitry@php.net>
Fri, 24 Jun 2005 12:33:53 +0000 (12:33 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 24 Jun 2005 12:33:53 +0000 (12:33 +0000)
Zend/zend_execute.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_gen.php

index 5b54cca1be65d74ca911d7495904631487c2b8ae..ea8f331f3cc75b9c889ff0034495f09f0d9a6a23 100644 (file)
@@ -194,6 +194,7 @@ typedef struct _zend_free_op {
 ZEND_API zval *zend_get_zval_ptr(znode *node, temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
 ZEND_API zval **zend_get_zval_ptr_ptr(znode *node, temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
 
+ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
 
 END_EXTERN_C()
 
index 3bc99c1c5abd3931e6d8789323e105bf84725849..5afbd445dd4a8c5025fe500b06cdd319d5b7c966 100644 (file)
@@ -3607,3 +3607,4 @@ ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
        }
 }
 
+ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
index 7c9db30753cec81008858ea72870f570281343ea..8476b9fdb2d7ad43fca44aba527f01743b821199 100644 (file)
@@ -29534,3 +29534,8 @@ ZEND_API void zend_vm_set_opcode_handler(zend_op* op)
        op->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);
 }
 
+ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS)
+{
+       return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+}
+
index a65153b5eb4dbfe4a65c1e8bfc774e2e03098b53..94e2a65e64a268f6bf034ce6fd67d0b4a7b203b2 100644 (file)
@@ -905,6 +905,7 @@ function gen_vm($def, $skel) {
        $helper         = null;
        $max_opcode_len = 0;
        $max_opcode     = 0;
+       $export         = array();
        foreach ($in as $line) {
                ++$lineno;
                if (strpos($line,"ZEND_VM_HANDLER(") === 0) {
@@ -977,6 +978,28 @@ function gen_vm($def, $skel) {
                        $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"");
                        $handler = null;
                        $list[$lineno] = array("helper"=>$helper);
+               } else if (strpos($line,"ZEND_VM_EXPORT_HANDLER(") === 0) {
+                       if (preg_match(
+                                       "/^ZEND_VM_EXPORT_HANDLER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_]+)\s*\)/",
+                                       $line,
+                                       $m) == 0) {
+                               die("ERROR ($def:$lineno): Invalid ZEND_VM_EXPORT_HANDLER definition.\n");
+                       }
+                       if (!isset($opnames[$m[2]])) {
+                               die("ERROR ($def:$lineno): opcode '{$m[2]}' is not defined.\n");
+                       }
+                       $export[] = array("handler",$m[1],$m[2]);
+               } else if (strpos($line,"ZEND_VM_EXPORT_HELPER(") === 0) {
+                       if (preg_match(
+                                       "/^ZEND_VM_EXPORT_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Za-z_]+)\s*\)/",
+                                       $line,
+                                       $m) == 0) {
+                               die("ERROR ($def:$lineno): Invalid ZEND_VM_EXPORT_HELPER definition.\n");
+                       }
+                       if (!isset($helpers[$m[2]])) {
+                               die("ERROR ($def:$lineno): helper '{$m[2]}' is not defined.\n");
+                       }
+                       $export[] = array("helper",$m[1],$m[2]);
                } else if ($handler !== null) {
                  // Add line of code to current opcode handler
                        $opcodes[$handler]["code"] .= $line;
@@ -1093,6 +1116,65 @@ function gen_vm($def, $skel) {
        out($f, "\top->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);\n");
        out($f, "}\n\n");
 
+       // Export handlers and helpers
+       if (count($export) > 0 && 
+           !ZEND_VM_OLD_EXECUTOR && 
+           ZEND_VM_KIND != ZEND_VM_KIND_CALL) {
+               out($f,"#undef EX\n");
+               out($f,"#define EX(element) execute_data->element\n\n");
+               out($f,"#undef ZEND_VM_CONTINUE\n");
+               out($f,"#undef ZEND_VM_RETURN\n");
+               out($f,"#undef ZEND_VM_DISPATCH\n");
+               out($f,"#undef ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL\n\n");
+               out($f,"#define ZEND_VM_CONTINUE()   return 0\n");
+               out($f,"#define ZEND_VM_RETURN()     return 1\n");
+               out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n");
+               out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n\n");
+       }
+       foreach ($export as $dsk) {
+               list($kind, $func, $name) = $dsk;
+               out($f, "ZEND_API int $func(");
+               if ($kind == "handler") {
+                       out($f, "ZEND_OPCODE_HANDLER_ARGS)\n");
+                       $code = $opcodes[$opnames[$name]]['code'];
+               } else {
+                       $h = $helpers[$name];
+                       if ($h['param'] == null) {
+                               out($f, "ZEND_OPCODE_HANDLER_ARGS)\n");
+                       } else {
+                               out($f, $h['param']. ", ZEND_OPCODE_HANDLER_ARGS)\n");
+                       }
+                       $code = $h['code'];
+               }
+               $done = 0;
+               if (ZEND_VM_OLD_EXECUTOR) {
+                       if ($kind == "handler") {
+                               out($f, "{\n\treturn ".$name."_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n");
+                               $done = 1;
+                       } else if ($helpers[$name]["param"] == null) {
+                               out($f, "{\n\treturn ".$name."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n");
+                               $done = 1;
+                       }
+               } else if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) {
+                       if ($kind == "handler") {
+                               $op = $opcodes[$opnames[$name]];
+                               if (isset($op['op1']["ANY"]) && isset($op['op2']["ANY"])) {
+                                       out($f, "{\n\treturn ".$name."_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n");
+                                       $done = 1;
+                               }
+                       } else if ($helpers[$name]["param"] == null) {
+                               $h = $helpers[$name];
+                               if (isset($h['op1']["ANY"]) && isset($h['op2']["ANY"])) {
+                                       out($f, "{\n\treturn ".$name."_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n}\n\n");
+                                       $done = 1;
+                               }
+                       }
+               }
+               if (!$done) {
+                       gen_code($f, 0, ZEND_VM_KIND_CALL, $code, 'ANY', 'ANY');
+               }
+       }
+
        fclose($f);
        echo "zend_vm_execute.h generated succesfull.\n";
 }