source: trunk/disassembler.c @ 930

Last change on this file since 930 was 930, checked in by moo, 22 months ago

fix disassembler for 2.4 literal

  • Property svn:eol-style set to native
File size: 4.6 KB
Line 
1#include "disassembler.h"
2#include "xcache.h"
3#include "utils.h"
4#include "processor.h"
5
6#define return_value dst
7
8/* sandbox {{{ */
9#undef TG
10#undef OG
11#define TG(x) (sandbox->tmp_##x)
12#define OG(x) (sandbox->orig_##x)
13/* }}} */
14
15#ifndef HAVE_XCACHE_OPCODE_SPEC_DEF
16#error disassembler cannot be built without xcache/opcode_spec_def.h
17#endif
18static void xc_dasm(xc_sandbox_t *sandbox, zval *dst, zend_op_array *op_array TSRMLS_DC) /* {{{ */
19{
20    Bucket *b;
21    zval *zv, *list;
22    xc_compile_result_t cr;
23    int bufsize = 2;
24    char *buf;
25    xc_dasm_t dasm;
26
27    xc_compile_result_init_cur(&cr, op_array TSRMLS_CC);
28
29    xc_apply_op_array(&cr, (apply_func_t) xc_undo_pass_two TSRMLS_CC);
30    xc_apply_op_array(&cr, (apply_func_t) xc_fix_opcode TSRMLS_CC);
31
32    /* go */
33    array_init(dst);
34
35    ALLOC_INIT_ZVAL(zv);
36    array_init(zv);
37    xc_dasm_zend_op_array(&dasm, zv, op_array TSRMLS_CC);
38    add_assoc_zval_ex(dst, ZEND_STRS("op_array"), zv);
39
40    buf = emalloc(bufsize);
41
42    ALLOC_INIT_ZVAL(list);
43    array_init(list);
44    b = TG(internal_function_tail) ? TG(internal_function_tail)->pListNext : TG(function_table).pListHead;
45    for (; b; b = b->pListNext) {
46        int keysize, keyLength;
47
48        ALLOC_INIT_ZVAL(zv);
49        array_init(zv);
50        xc_dasm_zend_function(&dasm, zv, b->pData TSRMLS_CC);
51
52        keysize = BUCKET_KEY_SIZE(b) + 2;
53        if (keysize > bufsize) {
54            do {
55                bufsize *= 2;
56            } while (keysize > bufsize);
57            buf = erealloc(buf, bufsize);
58        }
59        memcpy(buf, BUCKET_KEY_S(b), keysize);
60        buf[keysize - 2] = buf[keysize - 1] = ""[0];
61        keyLength = b->nKeyLength;
62#ifdef IS_UNICODE
63        if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
64            if (buf[0] == ""[0] && buf[1] == ""[0]) {
65                keyLength ++;
66            }
67        } else
68#endif
69        {
70            if (buf[0] == ""[0]) {
71                keyLength ++;
72            }
73        }
74
75        add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
76    }
77    add_assoc_zval_ex(dst, ZEND_STRS("function_table"), list);
78   
79    ALLOC_INIT_ZVAL(list);
80    array_init(list);
81    b = TG(internal_class_tail) ? TG(internal_class_tail)->pListNext : TG(class_table).pListHead;
82    for (; b; b = b->pListNext) {
83        int keysize, keyLength;
84
85        ALLOC_INIT_ZVAL(zv);
86        array_init(zv);
87        xc_dasm_zend_class_entry(&dasm, zv, CestToCePtr(*(xc_cest_t *)b->pData) TSRMLS_CC);
88
89        keysize = BUCKET_KEY_SIZE(b) + 2;
90        if (keysize > bufsize) {
91            do {
92                bufsize *= 2;
93            } while (keysize > bufsize);
94            buf = erealloc(buf, bufsize);
95        }
96        memcpy(buf, BUCKET_KEY_S(b), keysize);
97        buf[keysize - 2] = buf[keysize - 1] = ""[0];
98        keyLength = b->nKeyLength;
99#ifdef IS_UNICODE
100        if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
101            if (buf[0] == ""[0] && buf[1] == ""[0]) {
102                keyLength ++;
103            }
104        } else
105#endif
106        {
107            if (buf[0] == ""[0]) {
108                keyLength ++;
109            }
110        }
111        add_u_assoc_zval_ex(list, BUCKET_KEY_TYPE(b), ZSTR(buf), keyLength, zv);
112    }
113    efree(buf);
114    add_assoc_zval_ex(dst, ZEND_STRS("class_table"), list);
115
116    /*xc_apply_op_array(&cr, (apply_func_t) xc_redo_pass_two TSRMLS_CC);*/
117    xc_compile_result_free(&cr);
118
119    return;
120}
121/* }}} */
122void xc_dasm_string(zval *dst, zval *source TSRMLS_DC) /* {{{ */
123{
124    int catched;
125    zend_op_array *op_array = NULL;
126    xc_sandbox_t sandbox;
127    char *eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
128
129    xc_sandbox_init(&sandbox, eval_name TSRMLS_CC);
130
131    catched = 0;
132    zend_try {
133        op_array = compile_string(source, eval_name TSRMLS_CC);
134    } zend_catch {
135        catched = 1;
136    } zend_end_try();
137
138    if (catched || !op_array) {
139        goto err_compile;
140    }
141
142    xc_dasm(&sandbox, dst, op_array TSRMLS_CC);
143
144    /* free */
145    efree(eval_name);
146#ifdef ZEND_ENGINE_2
147    destroy_op_array(op_array TSRMLS_CC);
148#else
149    destroy_op_array(op_array);
150#endif
151    efree(op_array);
152    xc_sandbox_free(&sandbox, 0 TSRMLS_CC);
153    return;
154
155err_compile:
156    efree(eval_name);
157    xc_sandbox_free(&sandbox, 0 TSRMLS_CC);
158
159    RETURN_FALSE;
160}
161/* }}} */
162void xc_dasm_file(zval *dst, const char *filename TSRMLS_DC) /* {{{ */
163{
164    int catched;
165    zend_op_array *op_array = NULL;
166    xc_sandbox_t sandbox;
167    zval *zfilename;
168
169    MAKE_STD_ZVAL(zfilename);
170    zfilename->value.str.val = estrdup(filename);
171    zfilename->value.str.len = strlen(filename);
172    zfilename->type = IS_STRING;
173
174    xc_sandbox_init(&sandbox, zfilename->value.str.val TSRMLS_CC);
175
176    catched = 0;
177    zend_try {
178        op_array = compile_filename(ZEND_REQUIRE, zfilename TSRMLS_CC);
179    } zend_catch {
180        catched = 1;
181    } zend_end_try();
182
183    if (catched || !op_array) {
184        goto err_compile;
185    }
186
187    xc_dasm(&sandbox, dst, op_array TSRMLS_CC);
188
189    /* free */
190#ifdef ZEND_ENGINE_2
191    destroy_op_array(op_array TSRMLS_CC);
192#else
193    destroy_op_array(op_array);
194#endif
195    efree(op_array);
196    xc_sandbox_free(&sandbox, 0 TSRMLS_CC);
197    zval_dtor(zfilename);
198    FREE_ZVAL(zfilename);
199    return;
200
201err_compile:
202    xc_sandbox_free(&sandbox, 0 TSRMLS_CC);
203
204    zval_dtor(zfilename);
205    FREE_ZVAL(zfilename);
206    RETURN_FALSE;
207}
208/* }}} */
Note: See TracBrowser for help on using the repository browser.