source: trunk/mod_disassembler/xc_disassembler.c @ 1003

Last change on this file since 1003 was 1003, checked in by moo, 21 months ago

refactor: fix build for optimizer, use mod_* directories

  • Property svn:eol-style set to native
File size: 5.4 KB
RevLine 
[982]1#include "xc_disassembler.h"
[1]2#include "xcache.h"
[987]3#include "xcache/xc_utils.h"
4#include "xcache/xc_sandbox.h"
[982]5#include "xc_processor.h"
[1]6
[937]7static void xc_dasm(zval *output, zend_op_array *op_array TSRMLS_DC) /* {{{ */
[1]8{
[937]9    const Bucket *b;
[1]10    zval *zv, *list;
11    xc_compile_result_t cr;
12    int bufsize = 2;
13    char *buf;
[930]14    xc_dasm_t dasm;
[1]15
16    xc_compile_result_init_cur(&cr, op_array TSRMLS_CC);
17
18    xc_apply_op_array(&cr, (apply_func_t) xc_undo_pass_two TSRMLS_CC);
19    xc_apply_op_array(&cr, (apply_func_t) xc_fix_opcode TSRMLS_CC);
20
21    /* go */
[937]22    array_init(output);
[1]23
24    ALLOC_INIT_ZVAL(zv);
25    array_init(zv);
[930]26    xc_dasm_zend_op_array(&dasm, zv, op_array TSRMLS_CC);
[937]27    add_assoc_zval_ex(output, ZEND_STRS("op_array"), zv);
[1]28
[749]29    buf = emalloc(bufsize);
30
[1]31    ALLOC_INIT_ZVAL(list);
32    array_init(list);
[938]33    for (b = xc_sandbox_user_function_begin(TSRMLS_C); b; b = b->pListNext) {
[749]34        int keysize, keyLength;
35
[709]36        ALLOC_INIT_ZVAL(zv);
37        array_init(zv);
[930]38        xc_dasm_zend_function(&dasm, zv, b->pData TSRMLS_CC);
[709]39
[749]40        keysize = BUCKET_KEY_SIZE(b) + 2;
41        if (keysize > bufsize) {
42            do {
43                bufsize *= 2;
44            } while (keysize > bufsize);
45            buf = erealloc(buf, bufsize);
46        }
47        memcpy(buf, BUCKET_KEY_S(b), keysize);
48        buf[keysize - 2] = buf[keysize - 1] = ""[0];
49        keyLength = b->nKeyLength;
50#ifdef IS_UNICODE
51        if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
52            if (buf[0] == ""[0] && buf[1] == ""[0]) {
53                keyLength ++;
54            }
55        } else
56#endif
57        {
58            if (buf[0] == ""[0]) {
59                keyLength ++;
60            }
61        }
62
63        add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
[709]64    }
[937]65    add_assoc_zval_ex(output, ZEND_STRS("function_table"), list);
[1]66   
67    ALLOC_INIT_ZVAL(list);
68    array_init(list);
[938]69    for (b = xc_sandbox_user_class_begin(TSRMLS_C); b; b = b->pListNext) {
[714]70        int keysize, keyLength;
71
[1]72        ALLOC_INIT_ZVAL(zv);
73        array_init(zv);
[930]74        xc_dasm_zend_class_entry(&dasm, zv, CestToCePtr(*(xc_cest_t *)b->pData) TSRMLS_CC);
[1]75
76        keysize = BUCKET_KEY_SIZE(b) + 2;
77        if (keysize > bufsize) {
78            do {
79                bufsize *= 2;
80            } while (keysize > bufsize);
81            buf = erealloc(buf, bufsize);
82        }
[200]83        memcpy(buf, BUCKET_KEY_S(b), keysize);
[1]84        buf[keysize - 2] = buf[keysize - 1] = ""[0];
[714]85        keyLength = b->nKeyLength;
[1]86#ifdef IS_UNICODE
87        if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
88            if (buf[0] == ""[0] && buf[1] == ""[0]) {
[714]89                keyLength ++;
[1]90            }
91        } else
92#endif
93        {
94            if (buf[0] == ""[0]) {
[714]95                keyLength ++;
[1]96            }
97        }
[714]98        add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
[1]99    }
100    efree(buf);
[937]101    add_assoc_zval_ex(output, ZEND_STRS("class_table"), list);
[1]102
103    /*xc_apply_op_array(&cr, (apply_func_t) xc_redo_pass_two TSRMLS_CC);*/
104    xc_compile_result_free(&cr);
105}
106/* }}} */
[937]107typedef struct xc_dasm_sandboxed_t { /* {{{ */
108    enum Type {
109        xc_dasm_file_t
110        , xc_dasm_string_t
111    } type;
112    union {
113        zval *zfilename;
114        struct {
115            zval *source;
116            char *eval_name;
117        } compile_string;
118    } input;
119
120    zval *output;
[993]121} xc_dasm_sandboxed_t; /* }}} */
122zend_op_array *xc_dasm_sandboxed(void *data TSRMLS_DC) /* {{{ */
[1]123{
[937]124    zend_bool catched = 0;
[1]125    zend_op_array *op_array = NULL;
[937]126    xc_dasm_sandboxed_t *sandboxed_dasm = (xc_dasm_sandboxed_t *) data;
[1]127
128    zend_try {
[937]129        if (sandboxed_dasm->type == xc_dasm_file_t) {
130            op_array = compile_filename(ZEND_REQUIRE, sandboxed_dasm->input.zfilename TSRMLS_CC);
131        }
132        else {
133            op_array = compile_string(sandboxed_dasm->input.compile_string.source, sandboxed_dasm->input.compile_string.eval_name TSRMLS_CC);
134        }
[1]135    } zend_catch {
136        catched = 1;
137    } zend_end_try();
138
139    if (catched || !op_array) {
[937]140#define return_value sandboxed_dasm->output
141        RETVAL_FALSE;
142#undef return_value
143        return NULL;
[1]144    }
145
[937]146    xc_dasm(sandboxed_dasm->output, op_array TSRMLS_CC);
[1]147
148    /* free */
[289]149#ifdef ZEND_ENGINE_2
[1]150    destroy_op_array(op_array TSRMLS_CC);
[289]151#else
152    destroy_op_array(op_array);
153#endif
[1]154    efree(op_array);
155
[937]156    return NULL;
157} /* }}} */
158void xc_dasm_string(zval *output, zval *source TSRMLS_DC) /* {{{ */
159{
160    xc_dasm_sandboxed_t sandboxed_dasm;
161    char *eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
[1]162
[937]163    sandboxed_dasm.output = output;
164    sandboxed_dasm.type = xc_dasm_string_t;
165    sandboxed_dasm.input.compile_string.source = source;
166    sandboxed_dasm.input.compile_string.eval_name = eval_name;
167    xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, eval_name TSRMLS_CC);
168    efree(eval_name);
[1]169}
170/* }}} */
[937]171void xc_dasm_file(zval *output, const char *filename TSRMLS_DC) /* {{{ */
[1]172{
173    zval *zfilename;
[937]174    xc_dasm_sandboxed_t sandboxed_dasm;
[1]175
176    MAKE_STD_ZVAL(zfilename);
177    zfilename->value.str.val = estrdup(filename);
178    zfilename->value.str.len = strlen(filename);
179    zfilename->type = IS_STRING;
180
[937]181    sandboxed_dasm.output = output;
182    sandboxed_dasm.type = xc_dasm_file_t;
183    sandboxed_dasm.input.zfilename = zfilename;
184    xc_sandbox(&xc_dasm_sandboxed, (void *) &sandboxed_dasm, zfilename->value.str.val TSRMLS_CC);
[1]185
186    zval_dtor(zfilename);
187    FREE_ZVAL(zfilename);
188}
189/* }}} */
[993]190
191/* {{{ proto array xcache_dasm_file(string filename)
192   Disassemble file into opcode array by filename */
193PHP_FUNCTION(xcache_dasm_file)
194{
195    char *filename;
196    int filename_len;
197
198    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
199        return;
200    }
201    if (!filename_len) RETURN_FALSE;
202
203    xc_dasm_file(return_value, filename TSRMLS_CC);
204}
205/* }}} */
206/* {{{ proto array xcache_dasm_string(string code)
207   Disassemble php code into opcode array */
208PHP_FUNCTION(xcache_dasm_string)
209{
210    zval *code;
211
212    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &code) == FAILURE) {
213        return;
214    }
215    xc_dasm_string(return_value, code TSRMLS_CC);
216}
217/* }}} */
Note: See TracBrowser for help on using the repository browser.