~ubuntu-branches/ubuntu/hardy/php5/hardy-updates

« back to all changes in this revision

Viewing changes to Zend/zend_execute.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-10-09 03:14:32 UTC
  • Revision ID: james.westby@ubuntu.com-20051009031432-kspik3lobxstafv9
Tags: upstream-5.0.5
ImportĀ upstreamĀ versionĀ 5.0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   +----------------------------------------------------------------------+
 
3
   | Zend Engine                                                          |
 
4
   +----------------------------------------------------------------------+
 
5
   | Copyright (c) 1998-2004 Zend Technologies Ltd. (http://www.zend.com) |
 
6
   +----------------------------------------------------------------------+
 
7
   | This source file is subject to version 2.00 of the Zend license,     |
 
8
   | that is bundled with this package in the file LICENSE, and is        |
 
9
   | available through the world-wide-web at the following url:           |
 
10
   | http://www.zend.com/license/2_00.txt.                                |
 
11
   | If you did not receive a copy of the Zend license and are unable to  |
 
12
   | obtain it through the world-wide-web, please send a note to          |
 
13
   | license@zend.com so we can mail you a copy immediately.              |
 
14
   +----------------------------------------------------------------------+
 
15
   | Authors: Andi Gutmans <andi@zend.com>                                |
 
16
   |          Zeev Suraski <zeev@zend.com>                                |
 
17
   +----------------------------------------------------------------------+
 
18
*/
 
19
 
 
20
/* $Id: zend_execute.c,v 1.652.2.49 2005/09/01 13:21:56 dmitry Exp $ */
 
21
 
 
22
#define ZEND_INTENSIVE_DEBUGGING 0
 
23
 
 
24
#include <stdio.h>
 
25
#include <signal.h>
 
26
 
 
27
#include "zend.h"
 
28
#include "zend_compile.h"
 
29
#include "zend_execute.h"
 
30
#include "zend_API.h"
 
31
#include "zend_ptr_stack.h"
 
32
#include "zend_constants.h"
 
33
#include "zend_extensions.h"
 
34
#include "zend_fast_cache.h"
 
35
#include "zend_ini.h"
 
36
#include "zend_exceptions.h"
 
37
 
 
38
#define get_zval_ptr(node, Ts, should_free, type) _get_zval_ptr(node, Ts, should_free TSRMLS_CC)
 
39
#define get_zval_ptr_ptr(node, Ts, type) _get_zval_ptr_ptr(node, Ts TSRMLS_CC)
 
40
 
 
41
/* Prototypes */
 
42
static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type TSRMLS_DC);
 
43
static void zend_fetch_dimension_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type TSRMLS_DC);
 
44
static void zend_fetch_property_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type TSRMLS_DC);
 
45
static void zend_fetch_dimension_address_from_tmp_var(znode *result, znode *op1, znode *op2, temp_variable *Ts TSRMLS_DC);
 
46
static void zend_extension_statement_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
 
47
static void zend_extension_fcall_begin_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
 
48
static void zend_extension_fcall_end_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
 
49
 
 
50
#define RETURN_VALUE_USED(opline) (!((opline)->result.u.EA.type & EXT_TYPE_UNUSED))
 
51
 
 
52
#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
 
53
#define T(offset) (*(temp_variable *)((char *) Ts + offset))
 
54
 
 
55
#define TEMP_VAR_STACK_LIMIT 2000
 
56
 
 
57
#define MAKE_REAL_ZVAL_PTR(val) \
 
58
        do { \
 
59
                zval *_tmp; \
 
60
                ALLOC_ZVAL(_tmp); \
 
61
                _tmp->value = (val)->value; \
 
62
                _tmp->type = (val)->type; \
 
63
                _tmp->refcount = 1; \
 
64
                _tmp->is_ref = 0; \
 
65
                val = _tmp; \
 
66
        } while (0)
 
67
 
 
68
/* former zend_execute_locks.h */
 
69
static inline void zend_pzval_lock_func(zval *z)
 
70
{
 
71
        z->refcount++;
 
72
}
 
73
 
 
74
 
 
75
static inline void zend_pzval_unlock_func(zval *z TSRMLS_DC)
 
76
{
 
77
        z->refcount--;
 
78
        if (!z->refcount) {
 
79
                z->refcount = 1;
 
80
                z->is_ref = 0;
 
81
                EG(garbage)[EG(garbage_ptr)++] = z;
 
82
        }
 
83
}
 
84
 
 
85
static inline void zend_clean_garbage(TSRMLS_D)
 
86
{
 
87
        while (EG(garbage_ptr)) {
 
88
                zval_ptr_dtor(&EG(garbage)[--EG(garbage_ptr)]);
 
89
        }
 
90
}
 
91
 
 
92
#define PZVAL_UNLOCK(z) zend_pzval_unlock_func(z TSRMLS_CC)
 
93
#define PZVAL_LOCK(z) zend_pzval_lock_func(z)
 
94
#define RETURN_VALUE_UNUSED(pzn)        (((pzn)->u.EA.type & EXT_TYPE_UNUSED))
 
95
#define SELECTIVE_PZVAL_LOCK(pzv, pzn)  if (!RETURN_VALUE_UNUSED(pzn)) { PZVAL_LOCK(pzv); }
 
96
 
 
97
 
 
98
/* End of zend_execute_locks.h */
 
99
 
 
100
static inline zval *_get_zval_ptr(znode *node, temp_variable *Ts, zval **should_free TSRMLS_DC)
 
101
{
 
102
        switch (node->op_type) {
 
103
                case IS_CONST:
 
104
                        *should_free = 0;
 
105
                        return &node->u.constant;
 
106
                        break;
 
107
                case IS_TMP_VAR:
 
108
                        return *should_free = &T(node->u.var).tmp_var;
 
109
                        break;
 
110
                case IS_VAR:
 
111
                        if (T(node->u.var).var.ptr) {
 
112
                                PZVAL_UNLOCK(T(node->u.var).var.ptr);
 
113
                                *should_free = 0;
 
114
                                return T(node->u.var).var.ptr;
 
115
                        } else {
 
116
                                temp_variable *T = &T(node->u.var);
 
117
                                zval *str = T->str_offset.str;
 
118
 
 
119
                                /* string offset */
 
120
                                *should_free = &T(node->u.var).tmp_var;
 
121
 
 
122
                                if (T->str_offset.str->type != IS_STRING
 
123
                                        || ((int)T->str_offset.offset<0)
 
124
                                        || (T->str_offset.str->value.str.len <= T->str_offset.offset)) {
 
125
                                        zend_error(E_NOTICE, "Uninitialized string offset:  %d", T->str_offset.offset);
 
126
                                        T->tmp_var.value.str.val = empty_string;
 
127
                                        T->tmp_var.value.str.len = 0;
 
128
                                } else {
 
129
                                        char c = str->value.str.val[T->str_offset.offset];
 
130
 
 
131
                                        T->tmp_var.value.str.val = estrndup(&c, 1);
 
132
                                        T->tmp_var.value.str.len = 1;
 
133
                                }
 
134
                                PZVAL_UNLOCK(str);
 
135
                                T->tmp_var.refcount=1;
 
136
                                T->tmp_var.is_ref=1;
 
137
                                T->tmp_var.type = IS_STRING;
 
138
                                return &T->tmp_var;
 
139
                        }
 
140
                        break;
 
141
                case IS_UNUSED:
 
142
                        *should_free = 0;
 
143
                        return NULL;
 
144
                        break;
 
145
                EMPTY_SWITCH_DEFAULT_CASE()
 
146
        }
 
147
        return NULL;
 
148
}
 
149
 
 
150
static inline zval **_get_zval_ptr_ptr(znode *node, temp_variable *Ts TSRMLS_DC)
 
151
{
 
152
        if (node->op_type==IS_VAR) {
 
153
                if (T(node->u.var).var.ptr_ptr) {
 
154
                        PZVAL_UNLOCK(*T(node->u.var).var.ptr_ptr);
 
155
                } else {
 
156
                        /* string offset */
 
157
                        PZVAL_UNLOCK(T(node->u.var).str_offset.str);
 
158
                }
 
159
                return T(node->u.var).var.ptr_ptr;
 
160
        } else {
 
161
                return NULL;
 
162
        }
 
163
}
 
164
 
 
165
static inline void zend_fetch_property_address_inner(zval *object, znode *op2, znode *result, temp_variable *Ts, int type TSRMLS_DC)
 
166
{
 
167
        zval *prop_ptr = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
168
 
 
169
        if (EG(free_op2)) {
 
170
                MAKE_REAL_ZVAL_PTR(prop_ptr);
 
171
        }
 
172
 
 
173
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
 
174
                zval **ptr_ptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, prop_ptr TSRMLS_CC);
 
175
                if(NULL == ptr_ptr) {
 
176
                        if (Z_OBJ_HT_P(object)->read_property &&
 
177
                            (T(result->u.var).var.ptr = Z_OBJ_HT_P(object)->read_property(object, prop_ptr, BP_VAR_W TSRMLS_CC)) != NULL) {
 
178
                                T(result->u.var).var.ptr_ptr = &T(result->u.var).var.ptr;
 
179
                        } else {
 
180
                                zend_error(E_ERROR, "Cannot access undefined property for object with overloaded property access");
 
181
                        }
 
182
                } else {
 
183
                        T(result->u.var).var.ptr_ptr = ptr_ptr;
 
184
                }
 
185
        } else if (Z_OBJ_HT_P(object)->read_property) {
 
186
                T(result->u.var).var.ptr = Z_OBJ_HT_P(object)->read_property(object, prop_ptr, BP_VAR_W TSRMLS_CC);
 
187
                T(result->u.var).var.ptr_ptr = &T(result->u.var).var.ptr;
 
188
        } else {
 
189
                zend_error(E_WARNING, "This object doesn't support property references");
 
190
                T(result->u.var).var.ptr_ptr = &EG(error_zval_ptr);
 
191
        }
 
192
        
 
193
        if (EG(free_op2)) {
 
194
                zval_ptr_dtor(&prop_ptr);
 
195
        }
 
196
}
 
197
 
 
198
 
 
199
 
 
200
static inline void zend_switch_free(zend_op *opline, temp_variable *Ts TSRMLS_DC)
 
201
{
 
202
        switch (opline->op1.op_type) {
 
203
                case IS_VAR:
 
204
                        if (!T(opline->op1.u.var).var.ptr_ptr) {
 
205
                                temp_variable *T = &T(opline->op1.u.var);
 
206
                                /* perform the equivalent of equivalent of a
 
207
                                 * quick & silent get_zval_ptr, and FREE_OP
 
208
                                 */
 
209
                                PZVAL_UNLOCK(T->str_offset.str);
 
210
                        } else {
 
211
                                zval_ptr_dtor(&T(opline->op1.u.var).var.ptr);
 
212
                                if (opline->extended_value) { /* foreach() free */
 
213
                                        zval_ptr_dtor(&T(opline->op1.u.var).var.ptr);
 
214
                                }
 
215
                        }
 
216
                        break;
 
217
                case IS_TMP_VAR:
 
218
                        zendi_zval_dtor(T(opline->op1.u.var).tmp_var);
 
219
                        break;
 
220
                EMPTY_SWITCH_DEFAULT_CASE()
 
221
        }
 
222
}
 
223
 
 
224
void zend_assign_to_variable_reference(znode *result, zval **variable_ptr_ptr, zval **value_ptr_ptr, temp_variable *Ts TSRMLS_DC)
 
225
{
 
226
        zval *variable_ptr;
 
227
        zval *value_ptr;
 
228
 
 
229
        if (!value_ptr_ptr || !variable_ptr_ptr) {
 
230
                zend_error(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
 
231
                return;
 
232
        }
 
233
 
 
234
        variable_ptr = *variable_ptr_ptr;
 
235
        value_ptr = *value_ptr_ptr;
 
236
 
 
237
        if (variable_ptr == EG(error_zval_ptr) || value_ptr==EG(error_zval_ptr)) {
 
238
                variable_ptr_ptr = &EG(uninitialized_zval_ptr);
 
239
        } else if (variable_ptr != value_ptr) {
 
240
                if (!PZVAL_IS_REF(value_ptr)) {
 
241
                        /* break it away */
 
242
                        value_ptr->refcount--;
 
243
                        if (value_ptr->refcount>0) {
 
244
                                ALLOC_ZVAL(*value_ptr_ptr);
 
245
                                **value_ptr_ptr = *value_ptr;
 
246
                                value_ptr = *value_ptr_ptr;
 
247
                                zendi_zval_copy_ctor(*value_ptr);
 
248
                        }
 
249
                        value_ptr->refcount = 1;
 
250
                        value_ptr->is_ref = 1;
 
251
                }
 
252
                *variable_ptr_ptr = value_ptr;
 
253
                value_ptr->refcount++;
 
254
                
 
255
                variable_ptr->refcount--;
 
256
                if (variable_ptr->refcount==0) {
 
257
                        zendi_zval_dtor(*variable_ptr);
 
258
                        FREE_ZVAL(variable_ptr);
 
259
                }
 
260
        } else if (!variable_ptr->is_ref) {
 
261
                if (variable_ptr_ptr == value_ptr_ptr) {
 
262
                        SEPARATE_ZVAL(variable_ptr_ptr);
 
263
                } else if (variable_ptr==EG(uninitialized_zval_ptr)
 
264
                        || variable_ptr->refcount>2) {
 
265
                        /* we need to separate */
 
266
                        variable_ptr->refcount -= 2;
 
267
                        ALLOC_ZVAL(*variable_ptr_ptr);
 
268
                        **variable_ptr_ptr = *variable_ptr;
 
269
                        zval_copy_ctor(*variable_ptr_ptr);
 
270
                        *value_ptr_ptr = *variable_ptr_ptr;
 
271
                        (*variable_ptr_ptr)->refcount = 2;
 
272
                }
 
273
                (*variable_ptr_ptr)->is_ref = 1;
 
274
        }
 
275
 
 
276
        if (result && !(result->u.EA.type & EXT_TYPE_UNUSED)) {
 
277
                T(result->u.var).var.ptr_ptr = variable_ptr_ptr;
 
278
                SELECTIVE_PZVAL_LOCK(*variable_ptr_ptr, result);
 
279
                AI_USE_PTR(T(result->u.var).var);
 
280
        }
 
281
}
 
282
 
 
283
static inline void make_real_object(zval **object_ptr TSRMLS_DC)
 
284
{
 
285
/* this should modify object only if it's empty */
 
286
        if ((*object_ptr)->type == IS_NULL
 
287
                || ((*object_ptr)->type == IS_BOOL && (*object_ptr)->value.lval==0)
 
288
                || ((*object_ptr)->type == IS_STRING && (*object_ptr)->value.str.len == 0)) {
 
289
                if (!PZVAL_IS_REF(*object_ptr)) {
 
290
                        SEPARATE_ZVAL(object_ptr);
 
291
                }
 
292
                zend_error(E_STRICT, "Creating default object from empty value");
 
293
                object_init(*object_ptr);
 
294
        }
 
295
}
 
296
 
 
297
static inline zval **get_obj_zval_ptr_ptr(znode *op, temp_variable *Ts, int type TSRMLS_DC)
 
298
{
 
299
        if (op->op_type == IS_UNUSED) {
 
300
                if (EG(This)) {
 
301
                        /* this should actually never be modified, _ptr_ptr is modified only when
 
302
                           the object is empty */
 
303
                        return &EG(This);
 
304
                } else {
 
305
                        zend_error(E_ERROR, "Using $this when not in object context");
 
306
                }
 
307
        }
 
308
        return get_zval_ptr_ptr(op, Ts, type);
 
309
}
 
310
 
 
311
static inline zval *get_obj_zval_ptr(znode *op, temp_variable *Ts, zval **freeop, int type TSRMLS_DC)
 
312
{
 
313
        if (op->op_type == IS_UNUSED) {
 
314
                if (EG(This)) {
 
315
                        return EG(This);
 
316
                } else {
 
317
                        zend_error(E_ERROR, "Using $this when not in object context");
 
318
                }
 
319
        }
 
320
        return get_zval_ptr(op, Ts, freeop, type);
 
321
}
 
322
 
 
323
 
 
324
static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg TSRMLS_DC)
 
325
{
 
326
        zend_arg_info *cur_arg_info;
 
327
 
 
328
        if (!zf->common.arg_info
 
329
                || arg_num>zf->common.num_args) {
 
330
                return;
 
331
        }
 
332
 
 
333
        cur_arg_info = &zf->common.arg_info[arg_num-1];
 
334
 
 
335
        if (cur_arg_info->class_name) {
 
336
                if (!arg) {
 
337
                        zend_error(E_ERROR, "Argument %d must be an object of class %s", arg_num, cur_arg_info->class_name);
 
338
                }
 
339
                switch (Z_TYPE_P(arg)) {
 
340
                        case IS_NULL:
 
341
                                if (!cur_arg_info->allow_null) {
 
342
                                        zend_error(E_ERROR, "Argument %d must not be null", arg_num);
 
343
                                }
 
344
                                break;
 
345
                        case IS_OBJECT: {
 
346
                                        zend_class_entry *ce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
 
347
                                        if (!instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
 
348
                                                char *error_msg;
 
349
 
 
350
                                                if (ce->ce_flags & ZEND_ACC_INTERFACE) {
 
351
                                                        error_msg = "implement interface";
 
352
                                                } else {
 
353
                                                        error_msg = "be an instance of";
 
354
                                                }
 
355
                                                zend_error(E_ERROR, "Argument %d must %s %s", arg_num, error_msg, ce->name);
 
356
                                        }
 
357
                                }
 
358
                                break;
 
359
                        default:
 
360
                                zend_error(E_ERROR, "Argument %d must be an object of class %s", arg_num, cur_arg_info->class_name);
 
361
                                break;
 
362
                }
 
363
        }       
 
364
}
 
365
 
 
366
static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode *op2, znode *value_op, temp_variable *Ts, int opcode TSRMLS_DC)
 
367
{
 
368
        zval *object;
 
369
        zval *property_name = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
370
        zval *free_value;
 
371
        zval *value = get_zval_ptr(value_op, Ts, &free_value, BP_VAR_R);
 
372
        zval **retval = &T(result->u.var).var.ptr;
 
373
 
 
374
        make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
 
375
        object = *object_ptr;
 
376
        
 
377
        if (object->type != IS_OBJECT) {
 
378
                zend_error(E_WARNING, "Attempt to assign property of non-object");
 
379
                FREE_OP(Ts, op2, EG(free_op2));
 
380
                *retval = EG(uninitialized_zval_ptr);
 
381
 
 
382
                SELECTIVE_PZVAL_LOCK(*retval, result);
 
383
                FREE_OP(Ts, value_op, free_value);
 
384
                return;
 
385
        }
 
386
        
 
387
        /* here we are sure we are dealing with an object */
 
388
 
 
389
        /* separate our value if necessary */
 
390
        if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) {
 
391
                zval *orig_value = value;
 
392
                char *class_name;
 
393
                zend_uint class_name_len;
 
394
                int dup;
 
395
        
 
396
                ALLOC_ZVAL(value);
 
397
                *value = *orig_value;
 
398
                value->is_ref = 0;
 
399
                value->refcount = 0;
 
400
 
 
401
                dup = zend_get_object_classname(orig_value, &class_name, &class_name_len TSRMLS_CC);
 
402
 
 
403
                if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
 
404
                        zend_error(E_ERROR, "Trying to clone an uncloneable object of class %s",  class_name);
 
405
                }
 
406
 
 
407
                zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
 
408
                
 
409
                if(!dup)        {
 
410
                        efree(class_name);
 
411
                }
 
412
                
 
413
                value->value.obj = Z_OBJ_HANDLER_P(orig_value, clone_obj)(orig_value TSRMLS_CC);
 
414
        } else if (value_op->op_type == IS_TMP_VAR) {
 
415
                zval *orig_value = value;
 
416
 
 
417
                ALLOC_ZVAL(value);
 
418
                *value = *orig_value;
 
419
                value->is_ref = 0;
 
420
                value->refcount = 0;
 
421
        } else if (value_op->op_type == IS_CONST) {
 
422
                zval *orig_value = value;
 
423
 
 
424
                ALLOC_ZVAL(value);
 
425
                *value = *orig_value;
 
426
                value->is_ref = 0;
 
427
                value->refcount = 0;
 
428
                zval_copy_ctor(value);
 
429
        }
 
430
                
 
431
 
 
432
        value->refcount++;
 
433
        if (opcode == ZEND_ASSIGN_OBJ) {
 
434
                if (EG(free_op2)) {
 
435
                        MAKE_REAL_ZVAL_PTR(property_name);
 
436
                }
 
437
                Z_OBJ_HT_P(object)->write_property(object, property_name, value TSRMLS_CC);
 
438
        } else {
 
439
                /* Note:  property_name in this case is really the array index! */
 
440
                if (!Z_OBJ_HT_P(object)->write_dimension) {
 
441
                        zend_error(E_ERROR, "Cannot use object as array");
 
442
                }
 
443
                if (EG(free_op2)) {
 
444
                        MAKE_REAL_ZVAL_PTR(property_name);
 
445
                }
 
446
                Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
 
447
        }
 
448
        
 
449
        if (result) {
 
450
                T(result->u.var).var.ptr = value;
 
451
                T(result->u.var).var.ptr_ptr = &T(result->u.var).var.ptr; /* this is so that we could use it in FETCH_DIM_R, etc. - see bug #27876 */
 
452
                SELECTIVE_PZVAL_LOCK(value, result);
 
453
        }
 
454
        if (EG(free_op2)) {
 
455
                zval_ptr_dtor(&property_name);
 
456
        }
 
457
        zval_ptr_dtor(&value);
 
458
}
 
459
 
 
460
 
 
461
static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2, zval *value, int type, temp_variable *Ts TSRMLS_DC)
 
462
{
 
463
        zval **variable_ptr_ptr = get_zval_ptr_ptr(op1, Ts, BP_VAR_W);
 
464
        zval *variable_ptr;
 
465
        
 
466
        if (!variable_ptr_ptr) {
 
467
                temp_variable *T = &T(op1->u.var);
 
468
 
 
469
                if (T->str_offset.str->type == IS_STRING) do {
 
470
                        zval tmp;
 
471
                        zval *final_value = value;
 
472
 
 
473
                        if (((int)T->str_offset.offset < 0)) {
 
474
                                zend_error(E_WARNING, "Illegal string offset:  %d", T->str_offset.offset);
 
475
                                break;
 
476
                        }
 
477
                        if (T->str_offset.offset >= T->str_offset.str->value.str.len) {
 
478
                                zend_uint i;
 
479
 
 
480
                                if (T->str_offset.str->value.str.len==0) {
 
481
                                        STR_FREE(T->str_offset.str->value.str.val);
 
482
                                        T->str_offset.str->value.str.val = (char *) emalloc(T->str_offset.offset+1+1);
 
483
                                } else {
 
484
                                        T->str_offset.str->value.str.val = (char *) erealloc(T->str_offset.str->value.str.val, T->str_offset.offset+1+1);
 
485
                                }
 
486
                                for (i=T->str_offset.str->value.str.len; i<T->str_offset.offset; i++) {
 
487
                                        T->str_offset.str->value.str.val[i] = ' ';
 
488
                                }
 
489
                                T->str_offset.str->value.str.val[T->str_offset.offset+1] = 0;
 
490
                                T->str_offset.str->value.str.len = T->str_offset.offset+1;
 
491
                        }
 
492
 
 
493
                        if (value->type!=IS_STRING) {
 
494
                                tmp = *value;
 
495
                                if (op2 && op2->op_type == IS_VAR) {
 
496
                                        zval_copy_ctor(&tmp);
 
497
                                }
 
498
                                convert_to_string(&tmp);
 
499
                                final_value = &tmp;
 
500
                        }
 
501
 
 
502
                        T->str_offset.str->value.str.val[T->str_offset.offset] = final_value->value.str.val[0];
 
503
                        
 
504
                        if (op2) {
 
505
                                if (op2->op_type == IS_VAR) {
 
506
                                        if (value == &T(op2->u.var).tmp_var) {
 
507
                                                if (result->u.EA.type & EXT_TYPE_UNUSED) {
 
508
                                                        /* We are not going to use return value, drop it */
 
509
                                                        STR_FREE(value->value.str.val);
 
510
                                                } else {
 
511
                                                        /* We are going to use return value, make it real zval */
 
512
                                                        ALLOC_ZVAL(value);
 
513
                                                        *value = T(op2->u.var).tmp_var;
 
514
                                                        value->is_ref = 0;
 
515
                                                        value->refcount = 0; /* LOCK will increase it */
 
516
                                                }
 
517
                                        }
 
518
                                } else {
 
519
                                        if (final_value == &T(op2->u.var).tmp_var) {
 
520
                                                /* we can safely free final_value here
 
521
                                                 * because separation is done only
 
522
                                                 * in case op2->op_type == IS_VAR */
 
523
                                                STR_FREE(final_value->value.str.val);
 
524
                                        }
 
525
                                }
 
526
                        }
 
527
                        if (final_value == &tmp) {
 
528
                                zval_dtor(final_value);
 
529
                        }
 
530
                        /*
 
531
                         * the value of an assignment to a string offset is undefined
 
532
                        T(result->u.var).var = &T->str_offset.str;
 
533
                        */
 
534
                } while (0);
 
535
                /* zval_ptr_dtor(&T->str_offset.str); Nuke this line if it doesn't cause a leak */
 
536
                T->tmp_var.type = IS_STRING;
 
537
                
 
538
/*              T(result->u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr); */
 
539
                T(result->u.var).var.ptr_ptr = &value;
 
540
                SELECTIVE_PZVAL_LOCK(*T(result->u.var).var.ptr_ptr, result);
 
541
                AI_USE_PTR(T(result->u.var).var);
 
542
                return;
 
543
        }
 
544
 
 
545
        variable_ptr = *variable_ptr_ptr;
 
546
 
 
547
        if (variable_ptr == EG(error_zval_ptr)) {
 
548
                if (result) {
 
549
                        T(result->u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
 
550
                        SELECTIVE_PZVAL_LOCK(*T(result->u.var).var.ptr_ptr, result);
 
551
                        AI_USE_PTR(T(result->u.var).var);
 
552
                }
 
553
                if (type==IS_TMP_VAR) {
 
554
                        zval_dtor(value);
 
555
                }
 
556
                return;
 
557
        }
 
558
 
 
559
        if(Z_TYPE_P(variable_ptr) == IS_OBJECT && Z_OBJ_HANDLER_P(variable_ptr, set)) {
 
560
                /* TODO? ze1_compatibility_mode support */
 
561
                Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
 
562
                goto done_setting_var;
 
563
        }
 
564
        
 
565
        if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) {
 
566
                char *class_name;
 
567
                zend_uint class_name_len;
 
568
                int dup;
 
569
 
 
570
                dup = zend_get_object_classname(value, &class_name, &class_name_len TSRMLS_CC);
 
571
 
 
572
                if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
 
573
                        zend_error(E_ERROR, "Trying to clone an uncloneable object of class %s",  class_name);
 
574
                } else if (PZVAL_IS_REF(variable_ptr)) {
 
575
                        if (variable_ptr != value) {
 
576
                                zend_uint refcount = variable_ptr->refcount;
 
577
                                zval garbage;
 
578
                                
 
579
                                if (type != IS_TMP_VAR) {
 
580
                                        value->refcount++;
 
581
                                }
 
582
                        
 
583
                                garbage = *variable_ptr;
 
584
                                *variable_ptr = *value;
 
585
                                variable_ptr->refcount = refcount;
 
586
                                variable_ptr->is_ref = 1;
 
587
                                
 
588
                                zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
 
589
 
 
590
                                variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
 
591
 
 
592
                                if (type != IS_TMP_VAR) {
 
593
                                        value->refcount--;
 
594
                                }
 
595
 
 
596
                                zendi_zval_dtor(garbage);
 
597
                        }
 
598
                } else {
 
599
                        if (variable_ptr != value) {
 
600
                                value->refcount++;
 
601
                                variable_ptr->refcount--;
 
602
                                if (variable_ptr->refcount == 0) {
 
603
                                        zendi_zval_dtor(*variable_ptr);
 
604
                                } else {
 
605
                                        ALLOC_ZVAL(variable_ptr);
 
606
                                        *variable_ptr_ptr = variable_ptr;
 
607
                                }
 
608
                                *variable_ptr = *value;
 
609
                                INIT_PZVAL(variable_ptr);
 
610
                                zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
 
611
                                variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
 
612
                                zval_ptr_dtor(&value);
 
613
                        }
 
614
                }
 
615
 
 
616
                if(!dup) {
 
617
                        efree(class_name);
 
618
                }
 
619
 
 
620
        } else if (PZVAL_IS_REF(variable_ptr)) {
 
621
                if (variable_ptr!=value) {
 
622
                        zend_uint refcount = variable_ptr->refcount;
 
623
                        zval garbage;
 
624
                        
 
625
                        if (type!=IS_TMP_VAR) {
 
626
                                value->refcount++;
 
627
                        }
 
628
                        garbage = *variable_ptr;
 
629
                        *variable_ptr = *value;
 
630
                        variable_ptr->refcount = refcount;
 
631
                        variable_ptr->is_ref = 1;
 
632
                        if (type!=IS_TMP_VAR) {
 
633
                                zendi_zval_copy_ctor(*variable_ptr);
 
634
                                value->refcount--;
 
635
                        }
 
636
                        zendi_zval_dtor(garbage);
 
637
                }
 
638
        } else {
 
639
                variable_ptr->refcount--;
 
640
                if (variable_ptr->refcount==0) {
 
641
                        switch (type) {
 
642
                                case IS_VAR:
 
643
                                        /* break missing intentionally */
 
644
                                case IS_CONST:
 
645
                                        if (variable_ptr==value) {
 
646
                                                variable_ptr->refcount++;
 
647
                                        } else if (PZVAL_IS_REF(value)) {
 
648
                                                zval tmp;
 
649
                                                
 
650
                                                tmp = *value;
 
651
                                                zval_copy_ctor(&tmp);
 
652
                                                tmp.refcount=1;
 
653
                                                zendi_zval_dtor(*variable_ptr);
 
654
                                                *variable_ptr = tmp;
 
655
                                        } else {
 
656
                                                value->refcount++;
 
657
                                                zendi_zval_dtor(*variable_ptr);
 
658
                                                safe_free_zval_ptr(variable_ptr);
 
659
                                                *variable_ptr_ptr = value;
 
660
                                        }
 
661
                                        break;
 
662
                                case IS_TMP_VAR:
 
663
                                        zendi_zval_dtor(*variable_ptr);
 
664
                                        value->refcount=1;
 
665
                                        *variable_ptr = *value;
 
666
                                        break;
 
667
                                        EMPTY_SWITCH_DEFAULT_CASE()
 
668
                                                }
 
669
                } else { /* we need to split */
 
670
                        switch (type) {
 
671
                                case IS_VAR:
 
672
                                        /* break missing intentionally */
 
673
                                case IS_CONST:
 
674
                                        if (PZVAL_IS_REF(value) && value->refcount > 0) {
 
675
                                                ALLOC_ZVAL(variable_ptr);
 
676
                                                *variable_ptr_ptr = variable_ptr;
 
677
                                                *variable_ptr = *value;
 
678
                                                zval_copy_ctor(variable_ptr);
 
679
                                                variable_ptr->refcount=1;
 
680
                                                break;
 
681
                                        }
 
682
                                        *variable_ptr_ptr = value;
 
683
                                        value->refcount++;
 
684
                                        break;
 
685
                                case IS_TMP_VAR:
 
686
                                        ALLOC_ZVAL(*variable_ptr_ptr);
 
687
                                        value->refcount=1;
 
688
                                        **variable_ptr_ptr = *value;
 
689
                                        break;
 
690
                                        EMPTY_SWITCH_DEFAULT_CASE()
 
691
                                                }
 
692
                }
 
693
                (*variable_ptr_ptr)->is_ref=0;
 
694
        }
 
695
        
 
696
done_setting_var:
 
697
        if (result) {
 
698
                T(result->u.var).var.ptr_ptr = variable_ptr_ptr;
 
699
                SELECTIVE_PZVAL_LOCK(*variable_ptr_ptr, result);
 
700
                AI_USE_PTR(T(result->u.var).var);
 
701
        } 
 
702
}
 
703
 
 
704
 
 
705
/* Utility Functions for Extensions */
 
706
static void zend_extension_statement_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
 
707
{
 
708
        if (extension->statement_handler) {
 
709
                extension->statement_handler(op_array);
 
710
        }
 
711
}
 
712
 
 
713
 
 
714
static void zend_extension_fcall_begin_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
 
715
{
 
716
        if (extension->fcall_begin_handler) {
 
717
                extension->fcall_begin_handler(op_array);
 
718
        }
 
719
}
 
720
 
 
721
 
 
722
static void zend_extension_fcall_end_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
 
723
{
 
724
        if (extension->fcall_end_handler) {
 
725
                extension->fcall_end_handler(op_array);
 
726
        }
 
727
}
 
728
 
 
729
 
 
730
static void print_refcount(zval *p, char *str)
 
731
{
 
732
        print_refcount(NULL, NULL);
 
733
}
 
734
 
 
735
 
 
736
static inline HashTable *zend_get_target_symbol_table(zend_op *opline, temp_variable *Ts, int type, zval *variable TSRMLS_DC)
 
737
{
 
738
        switch (opline->op2.u.EA.type) {
 
739
                case ZEND_FETCH_LOCAL:
 
740
                        return EG(active_symbol_table);
 
741
                        break;
 
742
                case ZEND_FETCH_GLOBAL:
 
743
                        return &EG(symbol_table);
 
744
                        break;
 
745
                case ZEND_FETCH_STATIC:
 
746
                        if (!EG(active_op_array)->static_variables) {
 
747
                                ALLOC_HASHTABLE(EG(active_op_array)->static_variables);
 
748
                                zend_hash_init(EG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
 
749
                        }
 
750
                        return EG(active_op_array)->static_variables;
 
751
                        break;
 
752
                EMPTY_SWITCH_DEFAULT_CASE()
 
753
        }
 
754
        return NULL;
 
755
}
 
756
 
 
757
 
 
758
static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type TSRMLS_DC)
 
759
{
 
760
        zval *free_op1;
 
761
        zval *varname = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R);
 
762
        zval **retval;
 
763
        zval tmp_varname;
 
764
        HashTable *target_symbol_table;
 
765
        zend_bool free_tmp = 0;
 
766
 
 
767
        if (varname->type != IS_STRING) {
 
768
                tmp_varname = *varname;
 
769
                zval_copy_ctor(&tmp_varname);
 
770
                convert_to_string(&tmp_varname);
 
771
                varname = &tmp_varname;
 
772
                free_tmp = 1;
 
773
        }
 
774
 
 
775
        if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
 
776
                target_symbol_table = NULL;
 
777
                retval = zend_std_get_static_property(T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC);
 
778
        } else {
 
779
                if (opline->op2.u.EA.type == ZEND_FETCH_GLOBAL && opline->op1.op_type == IS_VAR) {
 
780
                        varname->refcount++;
 
781
                }
 
782
                target_symbol_table = zend_get_target_symbol_table(opline, Ts, type, varname TSRMLS_CC);
 
783
                if (!target_symbol_table) {
 
784
                        return;
 
785
                }
 
786
                if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) {
 
787
                        switch (type) {
 
788
                                case BP_VAR_R: 
 
789
                                        zend_error(E_NOTICE,"Undefined variable: %s", varname->value.str.val);
 
790
                                        /* break missing intentionally */
 
791
                                case BP_VAR_IS:
 
792
                                        retval = &EG(uninitialized_zval_ptr);
 
793
                                        break;
 
794
                                case BP_VAR_RW:
 
795
                                        zend_error(E_NOTICE,"Undefined variable: %s", varname->value.str.val);
 
796
                                        /* break missing intentionally */
 
797
                                case BP_VAR_W: {                                        
 
798
                                                zval *new_zval = &EG(uninitialized_zval);
 
799
 
 
800
                                                new_zval->refcount++;
 
801
                                                zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval);
 
802
                                        }
 
803
                                        break;
 
804
                                EMPTY_SWITCH_DEFAULT_CASE()
 
805
                        }
 
806
                }
 
807
                switch (opline->op2.u.EA.type) {
 
808
                        case ZEND_FETCH_LOCAL:
 
809
                                FREE_OP(Ts, &opline->op1, free_op1);
 
810
                                break;
 
811
                        case ZEND_FETCH_STATIC:
 
812
                                zval_update_constant(retval, (void*) 1 TSRMLS_CC);
 
813
                                break;
 
814
                }
 
815
        }
 
816
 
 
817
 
 
818
        if (free_tmp) {
 
819
                zval_dtor(varname);
 
820
        }
 
821
        T(opline->result.u.var).var.ptr_ptr = retval;
 
822
        SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
 
823
}
 
824
 
 
825
 
 
826
static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, znode *op2, temp_variable *Ts, int type TSRMLS_DC)
 
827
{
 
828
        zval *dim = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
829
        zval **retval;
 
830
        char *offset_key;
 
831
        int offset_key_length;
 
832
 
 
833
        switch (dim->type) {
 
834
                case IS_NULL:
 
835
                        offset_key = "";
 
836
                        offset_key_length = 0;
 
837
                        goto fetch_string_dim;
 
838
                case IS_STRING:
 
839
                        
 
840
                        offset_key = dim->value.str.val;
 
841
                        offset_key_length = dim->value.str.len;
 
842
                        
 
843
fetch_string_dim:
 
844
                        if (zend_symtable_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) {
 
845
                                switch (type) {
 
846
                                        case BP_VAR_R:
 
847
                                                zend_error(E_NOTICE, "Undefined index:  %s", offset_key);
 
848
                                                /* break missing intentionally */
 
849
                                        case BP_VAR_UNSET:
 
850
                                        case BP_VAR_IS:
 
851
                                                retval = &EG(uninitialized_zval_ptr);
 
852
                                                break;
 
853
                                        case BP_VAR_RW:
 
854
                                                zend_error(E_NOTICE,"Undefined index:  %s", offset_key);
 
855
                                                /* break missing intentionally */
 
856
                                        case BP_VAR_W: {
 
857
                                                        zval *new_zval = &EG(uninitialized_zval);
 
858
 
 
859
                                                        new_zval->refcount++;
 
860
                                                        zend_symtable_update(ht, offset_key, offset_key_length+1, &new_zval, sizeof(zval *), (void **) &retval);
 
861
                                                }
 
862
                                                break;
 
863
                                }
 
864
                        }
 
865
                        break;
 
866
                case IS_RESOURCE:
 
867
                        zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", dim->value.lval, dim->value.lval);
 
868
                        /* Fall Through */
 
869
                case IS_DOUBLE:
 
870
                case IS_BOOL: 
 
871
                case IS_LONG: {
 
872
                                long index;
 
873
 
 
874
                                if (dim->type == IS_DOUBLE) {
 
875
                                        index = (long)dim->value.dval;
 
876
                                } else {
 
877
                                        index = dim->value.lval;
 
878
                                }
 
879
                                if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) {
 
880
                                        switch (type) {
 
881
                                                case BP_VAR_R:
 
882
                                                        zend_error(E_NOTICE,"Undefined offset:  %ld", index);
 
883
                                                        /* break missing intentionally */
 
884
                                                case BP_VAR_UNSET:
 
885
                                                case BP_VAR_IS:
 
886
                                                        retval = &EG(uninitialized_zval_ptr);
 
887
                                                        break;
 
888
                                                case BP_VAR_RW:
 
889
                                                        zend_error(E_NOTICE,"Undefined offset:  %ld", index);
 
890
                                                        /* break missing intentionally */
 
891
                                                case BP_VAR_W: {
 
892
                                                        zval *new_zval = &EG(uninitialized_zval);
 
893
 
 
894
                                                        new_zval->refcount++;
 
895
                                                        zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval);
 
896
                                                }
 
897
                                                break;
 
898
                                        }
 
899
                                }
 
900
                        }
 
901
                        break;
 
902
                default: 
 
903
                        zend_error(E_WARNING, "Illegal offset type");
 
904
                        switch (type) {
 
905
                                case BP_VAR_R:
 
906
                                case BP_VAR_IS:
 
907
                                case BP_VAR_UNSET:
 
908
                                        retval = &EG(uninitialized_zval_ptr);
 
909
                                        break;
 
910
                                default:
 
911
                                        retval = &EG(error_zval_ptr);
 
912
                                        break;
 
913
                        }
 
914
                        break;
 
915
        }
 
916
        FREE_OP(Ts, op2, EG(free_op2));
 
917
        return retval;
 
918
}
 
919
 
 
920
static void zend_fetch_dimension_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type TSRMLS_DC)
 
921
{
 
922
        zval **container_ptr = get_zval_ptr_ptr(op1, Ts, type);
 
923
        zval *container;
 
924
        zval ***retval = &T(result->u.var).var.ptr_ptr;
 
925
 
 
926
        if (!container_ptr) {
 
927
                zend_error(E_ERROR, "Cannot use string offset as an array");
 
928
        }
 
929
        
 
930
        container = *container_ptr;
 
931
 
 
932
        if (container == EG(error_zval_ptr)) {
 
933
                *retval = &EG(error_zval_ptr);
 
934
                SELECTIVE_PZVAL_LOCK(**retval, result);
 
935
                return;
 
936
        }
 
937
 
 
938
        if (container->type==IS_NULL
 
939
                || (container->type==IS_BOOL && container->value.lval==0)
 
940
                || (container->type==IS_STRING && container->value.str.len==0)) {
 
941
                switch (type) {
 
942
                        case BP_VAR_RW:
 
943
                        case BP_VAR_W:
 
944
                                if (!PZVAL_IS_REF(container)) {
 
945
                                        SEPARATE_ZVAL(container_ptr);
 
946
                                        container = *container_ptr;
 
947
                                }
 
948
                                array_init(container);
 
949
                                break;
 
950
                }
 
951
        }
 
952
 
 
953
        switch (container->type) {
 
954
                case IS_ARRAY:
 
955
                        if ((type==BP_VAR_W || type==BP_VAR_RW) && container->refcount>1 && !PZVAL_IS_REF(container)) {
 
956
                                SEPARATE_ZVAL(container_ptr);
 
957
                                container = *container_ptr;
 
958
                        }
 
959
                        if (op2->op_type == IS_UNUSED) {
 
960
                                zval *new_zval = &EG(uninitialized_zval);
 
961
 
 
962
                                new_zval->refcount++;
 
963
                                if (zend_hash_next_index_insert(container->value.ht, &new_zval, sizeof(zval *), (void **) retval) == FAILURE) {
 
964
                                        zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
 
965
                                        *retval = &EG(error_zval_ptr);
 
966
                                        new_zval->refcount--; 
 
967
                                }
 
968
                        } else {
 
969
                                *retval = zend_fetch_dimension_address_inner(container->value.ht, op2, Ts, type TSRMLS_CC);
 
970
                        }
 
971
                        SELECTIVE_PZVAL_LOCK(**retval, result);
 
972
                        break;
 
973
                case IS_NULL:
 
974
                        /* for read-mode only */
 
975
                        get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
976
                        *retval = &EG(uninitialized_zval_ptr);
 
977
                        SELECTIVE_PZVAL_LOCK(**retval, result);
 
978
                        FREE_OP(Ts, op2, EG(free_op2));
 
979
                        if (type==BP_VAR_W || type==BP_VAR_RW) {
 
980
                                zend_error(E_WARNING, "Cannot use a NULL value as an array");
 
981
                        }
 
982
                        break;
 
983
                case IS_STRING: {
 
984
                                zval *offset;
 
985
                                zval tmp;
 
986
 
 
987
                                if (op2->op_type==IS_UNUSED) {
 
988
                                        zend_error(E_ERROR, "[] operator not supported for strings");
 
989
                                }
 
990
 
 
991
                                offset = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
992
 
 
993
                                if (offset->type != IS_LONG) {
 
994
                                        tmp = *offset;
 
995
                                        zval_copy_ctor(&tmp);
 
996
                                        convert_to_long(&tmp);
 
997
                                        offset = &tmp;
 
998
                                }
 
999
                                switch (type) {
 
1000
                                        case BP_VAR_R:
 
1001
                                        case BP_VAR_IS:
 
1002
                                        case BP_VAR_UNSET:
 
1003
                                                /* do nothing... */
 
1004
                                                break;
 
1005
                                        default:
 
1006
                                                SEPARATE_ZVAL_IF_NOT_REF(container_ptr);
 
1007
                                                break;
 
1008
                                }
 
1009
                                container = *container_ptr;
 
1010
                                T(result->u.var).str_offset.str = container;
 
1011
                                PZVAL_LOCK(container);
 
1012
                                T(result->u.var).str_offset.offset = offset->value.lval;
 
1013
                                FREE_OP(Ts, op2, EG(free_op2));
 
1014
                                *retval = NULL;
 
1015
                                return;
 
1016
                        }
 
1017
                        break;
 
1018
                case IS_OBJECT:
 
1019
                        if (!Z_OBJ_HT_P(container)->read_dimension) {
 
1020
                                zend_error(E_ERROR, "Cannot use object as array");
 
1021
                        } else {
 
1022
                                zval *dim = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
1023
                                zval *overloaded_result;
 
1024
 
 
1025
                                if (EG(free_op2)) {
 
1026
                                        MAKE_REAL_ZVAL_PTR(dim);
 
1027
                                }
 
1028
                                overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
 
1029
                                if (overloaded_result) {
 
1030
                                        switch (type) {
 
1031
                                                case BP_VAR_RW:
 
1032
                                                case BP_VAR_W:
 
1033
                                                        if (overloaded_result->type != IS_OBJECT
 
1034
                                                                && !overloaded_result->is_ref) {
 
1035
                                                                zend_error(E_ERROR, "Objects used as arrays in post/pre increment/decrement must return values by reference");
 
1036
                                                        }
 
1037
                                                        break;
 
1038
                                        }
 
1039
 
 
1040
                                        *retval = &overloaded_result;
 
1041
                                } else {
 
1042
                                        *retval = &EG(error_zval_ptr);
 
1043
                                }
 
1044
                                AI_USE_PTR(T(result->u.var).var);
 
1045
                                SELECTIVE_PZVAL_LOCK(**retval, result);
 
1046
                                if (EG(free_op2)) {
 
1047
                                        zval_ptr_dtor(&dim);
 
1048
                                }
 
1049
                        }
 
1050
                        break;
 
1051
                default: {
 
1052
                                get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
1053
 
 
1054
                                switch (type) {
 
1055
                                        case BP_VAR_UNSET:
 
1056
                                                zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
 
1057
                                                /* break missing intentionally */
 
1058
                                        case BP_VAR_R:
 
1059
                                        case BP_VAR_IS:
 
1060
                                                *retval = &EG(uninitialized_zval_ptr);
 
1061
                                                break;
 
1062
                                        default:
 
1063
                                                *retval = &EG(error_zval_ptr);
 
1064
                                                break;
 
1065
                                }
 
1066
                                FREE_OP(Ts, op2, EG(free_op2));
 
1067
                                SELECTIVE_PZVAL_LOCK(**retval, result);
 
1068
                                if (type==BP_VAR_W || type==BP_VAR_RW) {
 
1069
                                        zend_error(E_WARNING, "Cannot use a scalar value as an array");
 
1070
                                }
 
1071
                        }
 
1072
                        break;
 
1073
        }
 
1074
}
 
1075
 
 
1076
 
 
1077
static void zend_fetch_dimension_address_from_tmp_var(znode *result, znode *op1, znode *op2, temp_variable *Ts TSRMLS_DC)
 
1078
{
 
1079
        zval *free_op1;
 
1080
        zval *container = get_zval_ptr(op1, Ts, &free_op1, BP_VAR_R);
 
1081
 
 
1082
        if (container->type != IS_ARRAY) {
 
1083
                T(result->u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
 
1084
                SELECTIVE_PZVAL_LOCK(*T(result->u.var).var.ptr_ptr, result);
 
1085
                return;
 
1086
        }
 
1087
 
 
1088
        T(result->u.var).var.ptr_ptr = zend_fetch_dimension_address_inner(container->value.ht, op2, Ts, BP_VAR_R TSRMLS_CC);
 
1089
        SELECTIVE_PZVAL_LOCK(*T(result->u.var).var.ptr_ptr, result);
 
1090
}
 
1091
 
 
1092
static void zend_fetch_property_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type TSRMLS_DC)
 
1093
{
 
1094
        zval **container_ptr = get_obj_zval_ptr_ptr(op1, Ts, type TSRMLS_CC);
 
1095
        zval *container;
 
1096
        zval ***retval = &T(result->u.var).var.ptr_ptr;
 
1097
        
 
1098
        container = *container_ptr;
 
1099
        if (container == EG(error_zval_ptr)) {
 
1100
                *retval = &EG(error_zval_ptr);
 
1101
                SELECTIVE_PZVAL_LOCK(**retval, result);
 
1102
                return;
 
1103
        }
 
1104
        /* this should modify object only if it's empty */
 
1105
        if (container->type == IS_NULL
 
1106
                || (container->type == IS_BOOL && container->value.lval==0)
 
1107
                || (container->type == IS_STRING && container->value.str.len == 0)) {
 
1108
                switch (type) {
 
1109
                        case BP_VAR_RW:
 
1110
                        case BP_VAR_W:
 
1111
                                if (!PZVAL_IS_REF(container)) {
 
1112
                                        SEPARATE_ZVAL(container_ptr);
 
1113
                                        container = *container_ptr;
 
1114
                                }
 
1115
                                object_init(container);
 
1116
                                break;
 
1117
                }
 
1118
        }
 
1119
        
 
1120
        if (container->type != IS_OBJECT) {
 
1121
                get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
1122
                FREE_OP(Ts, op2, EG(free_op2));
 
1123
                if (type == BP_VAR_R || type == BP_VAR_IS) {
 
1124
                        *retval = &EG(uninitialized_zval_ptr);
 
1125
                } else {
 
1126
                        *retval = &EG(error_zval_ptr);
 
1127
                }
 
1128
                SELECTIVE_PZVAL_LOCK(**retval, result);
 
1129
                return;
 
1130
        }
 
1131
        
 
1132
        
 
1133
        if ((type==BP_VAR_W || type==BP_VAR_RW) && container->refcount>1 && !PZVAL_IS_REF(container)) {
 
1134
                SEPARATE_ZVAL(container_ptr);
 
1135
                container = *container_ptr;
 
1136
        }
 
1137
        zend_fetch_property_address_inner(container, op2, result, Ts, type TSRMLS_CC);
 
1138
        SELECTIVE_PZVAL_LOCK(**retval, result);
 
1139
}
 
1140
 
 
1141
static void zend_fetch_property_address_read(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type TSRMLS_DC)
 
1142
{
 
1143
        zval *container;
 
1144
        zval **retval;
 
1145
        
 
1146
        retval = &T(result->u.var).var.ptr;
 
1147
        T(result->u.var).var.ptr_ptr = retval;
 
1148
 
 
1149
        container = get_obj_zval_ptr(op1, Ts, &EG(free_op1), type TSRMLS_CC);
 
1150
 
 
1151
        if (container == EG(error_zval_ptr)) {
 
1152
                *retval = EG(error_zval_ptr);
 
1153
                SELECTIVE_PZVAL_LOCK(*retval, result);
 
1154
                return;
 
1155
        }
 
1156
 
 
1157
 
 
1158
        if (container->type != IS_OBJECT) {
 
1159
                zend_error(E_NOTICE, "Trying to get property of non-object");
 
1160
 
 
1161
                if (type==BP_VAR_R || type==BP_VAR_IS) {
 
1162
                        *retval = EG(uninitialized_zval_ptr);
 
1163
                } else {
 
1164
                        *retval = EG(error_zval_ptr);
 
1165
                }
 
1166
                SELECTIVE_PZVAL_LOCK(*retval, result);
 
1167
        } else {
 
1168
                zval *offset;
 
1169
 
 
1170
                offset = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
1171
                if (EG(free_op2)) {
 
1172
                        MAKE_REAL_ZVAL_PTR(offset);
 
1173
                }
 
1174
 
 
1175
                /* here we are sure we are dealing with an object */
 
1176
                *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
1177
 
 
1178
                if (RETURN_VALUE_UNUSED(result) && ((*retval)->refcount == 0)) {
 
1179
                        zval_dtor(*retval);
 
1180
                        FREE_ZVAL(*retval);
 
1181
                } else {
 
1182
                        SELECTIVE_PZVAL_LOCK(*retval, result);
 
1183
                }
 
1184
 
 
1185
                if (EG(free_op2)) {
 
1186
                        zval_ptr_dtor(&offset);
 
1187
                }
 
1188
        }
 
1189
}
 
1190
 
 
1191
static void zend_pre_incdec_property(znode *result, znode *op1, znode *op2, temp_variable * Ts, int (*incdec_op)(zval *) TSRMLS_DC)
 
1192
{
 
1193
        zval **object_ptr = get_obj_zval_ptr_ptr(op1, Ts, BP_VAR_W TSRMLS_CC);
 
1194
        zval *object;
 
1195
        zval *property = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
1196
        zval **retval = &T(result->u.var).var.ptr;
 
1197
        int have_get_ptr = 0;
 
1198
 
 
1199
        make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
 
1200
        object = *object_ptr;
 
1201
        
 
1202
        if (object->type != IS_OBJECT) {
 
1203
                zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
 
1204
                FREE_OP(Ts, op2, EG(free_op2));
 
1205
                *retval = EG(uninitialized_zval_ptr);
 
1206
 
 
1207
                SELECTIVE_PZVAL_LOCK(*retval, result);
 
1208
                return;
 
1209
        }
 
1210
        
 
1211
        if (EG(free_op2)) {
 
1212
                MAKE_REAL_ZVAL_PTR(property);
 
1213
        }
 
1214
 
 
1215
        /* here we are sure we are dealing with an object */
 
1216
 
 
1217
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
 
1218
                zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
 
1219
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
 
1220
                        SEPARATE_ZVAL_IF_NOT_REF(zptr);
 
1221
 
 
1222
                        have_get_ptr = 1;
 
1223
                        incdec_op(*zptr);
 
1224
                        *retval = *zptr;
 
1225
                        SELECTIVE_PZVAL_LOCK(*retval, result);
 
1226
                }
 
1227
        }
 
1228
 
 
1229
        if (!have_get_ptr) {
 
1230
                zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_RW TSRMLS_CC);
 
1231
 
 
1232
                if (z->type == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
 
1233
                        zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);
 
1234
 
 
1235
                        if (z->refcount == 0) {
 
1236
                                zval_dtor(z);
 
1237
                                FREE_ZVAL(z);
 
1238
                        }
 
1239
                        z = value;
 
1240
                }
 
1241
                z->refcount++;
 
1242
                SEPARATE_ZVAL_IF_NOT_REF(&z);
 
1243
                incdec_op(z);
 
1244
                *retval = z;
 
1245
                Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
 
1246
                SELECTIVE_PZVAL_LOCK(*retval, result);
 
1247
                zval_ptr_dtor(&z);
 
1248
        }
 
1249
        
 
1250
        if (EG(free_op2)) {
 
1251
                zval_ptr_dtor(&property);
 
1252
        }
 
1253
}
 
1254
 
 
1255
static void zend_post_incdec_property(znode *result, znode *op1, znode *op2, temp_variable * Ts, int (*incdec_op)(zval *) TSRMLS_DC)
 
1256
{
 
1257
        zval **object_ptr = get_obj_zval_ptr_ptr(op1, Ts, BP_VAR_W TSRMLS_CC);
 
1258
        zval *object;
 
1259
        zval *property = get_zval_ptr(op2, Ts, &EG(free_op2), BP_VAR_R);
 
1260
        zval *retval = &T(result->u.var).tmp_var;
 
1261
        int have_get_ptr = 0;
 
1262
 
 
1263
        make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
 
1264
        object = *object_ptr;
 
1265
        
 
1266
        if (object->type != IS_OBJECT) {
 
1267
                zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
 
1268
                FREE_OP(Ts, op2, EG(free_op2));
 
1269
                *retval = *EG(uninitialized_zval_ptr);
 
1270
                return;
 
1271
        }
 
1272
        
 
1273
        if (EG(free_op2)) {
 
1274
                MAKE_REAL_ZVAL_PTR(property);
 
1275
        }
 
1276
 
 
1277
        /* here we are sure we are dealing with an object */
 
1278
 
 
1279
        if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
 
1280
                zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
 
1281
                if (zptr != NULL) {                     /* NULL means no success in getting PTR */
 
1282
                        have_get_ptr = 1;
 
1283
                        SEPARATE_ZVAL_IF_NOT_REF(zptr);
 
1284
                        
 
1285
                        *retval = **zptr;
 
1286
                        zendi_zval_copy_ctor(*retval);
 
1287
                        
 
1288
                        incdec_op(*zptr);
 
1289
 
 
1290
                }
 
1291
        }
 
1292
 
 
1293
        if (!have_get_ptr) {
 
1294
                zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_RW TSRMLS_CC);
 
1295
                zval *z_copy;
 
1296
 
 
1297
                if (z->type == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
 
1298
                        zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);
 
1299
 
 
1300
                        if (z->refcount == 0) {
 
1301
                                zval_dtor(z);
 
1302
                                FREE_ZVAL(z);
 
1303
                        }
 
1304
                        z = value;
 
1305
                }
 
1306
                *retval = *z;
 
1307
                zendi_zval_copy_ctor(*retval);
 
1308
                ALLOC_ZVAL(z_copy);
 
1309
                *z_copy = *z;
 
1310
                zendi_zval_copy_ctor(*z_copy);
 
1311
                INIT_PZVAL(z_copy);
 
1312
                incdec_op(z_copy);
 
1313
                z->refcount++;
 
1314
                Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC);
 
1315
                zval_ptr_dtor(&z_copy);
 
1316
                /* this would destroy z if it was returned with refcount == 0 and undo
 
1317
                   recount++ above otherwise */
 
1318
                zval_ptr_dtor(&z);
 
1319
        }
 
1320
        
 
1321
        if (EG(free_op2)) {
 
1322
                zval_ptr_dtor(&property);
 
1323
        }
 
1324
}
 
1325
 
 
1326
 
 
1327
#if ZEND_INTENSIVE_DEBUGGING
 
1328
 
 
1329
#define CHECK_SYMBOL_TABLES()                                                                                                           \
 
1330
        zend_hash_apply(&EG(symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC); \
 
1331
        if (&EG(symbol_table)!=EG(active_symbol_table)) {                                                               \
 
1332
                zend_hash_apply(EG(active_symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC);   \
 
1333
        }
 
1334
 
 
1335
static int zend_check_symbol(zval **pz TSRMLS_DC)
 
1336
{
 
1337
        if (Z_TYPE_PP(pz) > 9) {
 
1338
                fprintf(stderr, "Warning!  %x has invalid type!\n", *pz);
 
1339
        } else if (Z_TYPE_PP(pz) == IS_ARRAY) {
 
1340
                zend_hash_apply(Z_ARRVAL_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
 
1341
        } else if (Z_TYPE_PP(pz) == IS_OBJECT) {
 
1342
                
 
1343
                /* OBJ-TBI - doesn't support new object model! */
 
1344
                zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
 
1345
        }
 
1346
 
 
1347
        return 0;
 
1348
}
 
1349
 
 
1350
 
 
1351
#else
 
1352
#define CHECK_SYMBOL_TABLES()
 
1353
#endif
 
1354
 
 
1355
#define NEXT_OPCODE()           \
 
1356
        CHECK_SYMBOL_TABLES()   \
 
1357
        EX(opline)++;                   \
 
1358
        return 0; /* CHECK_ME */
 
1359
 
 
1360
#define SET_OPCODE(new_op)      \
 
1361
        CHECK_SYMBOL_TABLES()   \
 
1362
        EX(opline) = new_op; \
 
1363
 
 
1364
#define INC_OPCODE()                    \
 
1365
        if (!EG(exception)) {           \
 
1366
                CHECK_SYMBOL_TABLES()   \
 
1367
                EX(opline)++;                   \
 
1368
        }
 
1369
 
 
1370
#define RETURN_FROM_EXECUTE_LOOP(execute_data)                                                          \
 
1371
        if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) {                                           \
 
1372
                free_alloca(EX(Ts));                                                                                                    \
 
1373
        } else {                                                                \
 
1374
                efree(EX(Ts));                                                  \
 
1375
        }                                                                       \
 
1376
        EG(in_execution) = EX(original_in_execution);                                                   \
 
1377
        EG(current_execute_data) = EX(prev_execute_data);                                               \
 
1378
        return 1; /* CHECK_ME */
 
1379
 
 
1380
ZEND_API opcode_handler_t zend_opcode_handlers[512];
 
1381
 
 
1382
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
 
1383
{
 
1384
        ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, (*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr, execute_data_ptr->object, return_value_used TSRMLS_CC);
 
1385
}
 
1386
 
 
1387
ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
 
1388
{
 
1389
        zend_execute_data execute_data;
 
1390
 
 
1391
        /* Initialize execute_data */
 
1392
        EX(fbc) = NULL;
 
1393
        EX(object) = NULL;
 
1394
        if (op_array->T < TEMP_VAR_STACK_LIMIT) {
 
1395
                EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T);
 
1396
        } else {
 
1397
                EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0);
 
1398
        }
 
1399
        EX(op_array) = op_array;
 
1400
        EX(original_in_execution) = EG(in_execution);
 
1401
        EX(prev_execute_data) = EG(current_execute_data);
 
1402
        EG(current_execute_data) = &execute_data;
 
1403
 
 
1404
        EG(in_execution) = 1;
 
1405
        if (op_array->start_op) {
 
1406
                SET_OPCODE(op_array->start_op);
 
1407
        } else {
 
1408
                SET_OPCODE(op_array->opcodes);
 
1409
        }
 
1410
 
 
1411
        if (op_array->uses_this && EG(This)) {
 
1412
                EG(This)->refcount++; /* For $this pointer */
 
1413
                if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
 
1414
                        EG(This)->refcount--;
 
1415
                }
 
1416
        }
 
1417
 
 
1418
        EG(opline_ptr) = &EX(opline);
 
1419
 
 
1420
        EX(function_state).function = (zend_function *) op_array;
 
1421
        EG(function_state_ptr) = &EX(function_state);
 
1422
#if ZEND_DEBUG
 
1423
        /* function_state.function_symbol_table is saved as-is to a stack,
 
1424
         * which is an intentional UMR.  Shut it up if we're in DEBUG.
 
1425
         */
 
1426
        EX(function_state).function_symbol_table = NULL;
 
1427
#endif
 
1428
        
 
1429
        while (1) {
 
1430
#ifdef ZEND_WIN32
 
1431
                if (EG(timed_out)) {
 
1432
                        zend_timeout(0);
 
1433
                }
 
1434
#endif
 
1435
 
 
1436
                zend_clean_garbage(TSRMLS_C);
 
1437
                if (EX(opline)->handler(&execute_data, EX(opline), op_array TSRMLS_CC)) {
 
1438
                        return;
 
1439
                }
 
1440
        }
 
1441
        zend_error(E_ERROR, "Arrived at end of main loop which shouldn't happen");
 
1442
}
 
1443
 
 
1444
/* CHECK_ME */
 
1445
#undef EX
 
1446
#define EX(element) execute_data->element
 
1447
 
 
1448
int zend_add_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1449
{
 
1450
        add_function(&EX_T(opline->result.u.var).tmp_var, 
 
1451
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1452
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1453
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1454
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1455
        NEXT_OPCODE();
 
1456
}
 
1457
 
 
1458
 
 
1459
int zend_sub_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1460
{
 
1461
        sub_function(&EX_T(opline->result.u.var).tmp_var, 
 
1462
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1463
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1464
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1465
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1466
        NEXT_OPCODE();
 
1467
}
 
1468
 
 
1469
 
 
1470
int zend_mul_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1471
{
 
1472
        mul_function(&EX_T(opline->result.u.var).tmp_var, 
 
1473
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1474
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1475
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1476
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1477
        NEXT_OPCODE();
 
1478
}
 
1479
 
 
1480
 
 
1481
int zend_div_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1482
{
 
1483
        div_function(&EX_T(opline->result.u.var).tmp_var, 
 
1484
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1485
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1486
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1487
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1488
        NEXT_OPCODE();
 
1489
}
 
1490
 
 
1491
 
 
1492
int zend_mod_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1493
{
 
1494
        mod_function(&EX_T(opline->result.u.var).tmp_var, 
 
1495
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1496
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1497
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1498
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1499
        NEXT_OPCODE();
 
1500
}
 
1501
 
 
1502
 
 
1503
int zend_sl_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1504
{
 
1505
        shift_left_function(&EX_T(opline->result.u.var).tmp_var, 
 
1506
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1507
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1508
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1509
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1510
        NEXT_OPCODE();
 
1511
}
 
1512
 
 
1513
 
 
1514
int zend_sr_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1515
{
 
1516
        shift_right_function(&EX_T(opline->result.u.var).tmp_var, 
 
1517
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1518
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1519
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1520
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1521
        NEXT_OPCODE();
 
1522
}
 
1523
 
 
1524
 
 
1525
int zend_concat_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1526
{
 
1527
        concat_function(&EX_T(opline->result.u.var).tmp_var, 
 
1528
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1529
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1530
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1531
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1532
        NEXT_OPCODE();
 
1533
}
 
1534
 
 
1535
 
 
1536
int zend_is_identical_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1537
{
 
1538
        is_identical_function(&EX_T(opline->result.u.var).tmp_var, 
 
1539
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1540
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1541
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1542
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1543
        NEXT_OPCODE();
 
1544
}
 
1545
 
 
1546
 
 
1547
int zend_is_not_identical_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1548
{
 
1549
        is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, 
 
1550
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1551
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1552
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1553
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1554
        NEXT_OPCODE();
 
1555
}
 
1556
 
 
1557
 
 
1558
int zend_is_equal_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1559
{
 
1560
        is_equal_function(&EX_T(opline->result.u.var).tmp_var, 
 
1561
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1562
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1563
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1564
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1565
        NEXT_OPCODE();
 
1566
}
 
1567
 
 
1568
 
 
1569
int zend_is_not_equal_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1570
{
 
1571
        is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, 
 
1572
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1573
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1574
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1575
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1576
        NEXT_OPCODE();
 
1577
}
 
1578
 
 
1579
 
 
1580
int zend_is_smaller_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1581
{
 
1582
        is_smaller_function(&EX_T(opline->result.u.var).tmp_var, 
 
1583
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1584
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1585
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1586
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1587
        NEXT_OPCODE();
 
1588
}
 
1589
 
 
1590
 
 
1591
int zend_is_smaller_or_equal_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1592
{
 
1593
        is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, 
 
1594
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1595
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1596
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1597
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1598
        NEXT_OPCODE();
 
1599
}
 
1600
 
 
1601
 
 
1602
int zend_bw_or_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1603
{
 
1604
        bitwise_or_function(&EX_T(opline->result.u.var).tmp_var, 
 
1605
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1606
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1607
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1608
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1609
        NEXT_OPCODE();
 
1610
}
 
1611
 
 
1612
 
 
1613
int zend_bw_and_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1614
{
 
1615
        bitwise_and_function(&EX_T(opline->result.u.var).tmp_var, 
 
1616
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1617
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1618
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1619
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1620
        NEXT_OPCODE();
 
1621
}
 
1622
 
 
1623
 
 
1624
int zend_bw_xor_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1625
{
 
1626
        bitwise_xor_function(&EX_T(opline->result.u.var).tmp_var, 
 
1627
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1628
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1629
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1630
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1631
        NEXT_OPCODE();
 
1632
}
 
1633
 
 
1634
 
 
1635
int zend_bool_xor_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1636
{
 
1637
        boolean_xor_function(&EX_T(opline->result.u.var).tmp_var, 
 
1638
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
1639
                get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
1640
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1641
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1642
        NEXT_OPCODE();
 
1643
}
 
1644
 
 
1645
 
 
1646
int zend_bw_not_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1647
{
 
1648
        bitwise_not_function(&EX_T(opline->result.u.var).tmp_var,
 
1649
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R) TSRMLS_CC);
 
1650
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1651
        NEXT_OPCODE();
 
1652
}
 
1653
 
 
1654
 
 
1655
int zend_bool_not_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1656
{
 
1657
        boolean_not_function(&EX_T(opline->result.u.var).tmp_var,
 
1658
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R) TSRMLS_CC);
 
1659
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
1660
        NEXT_OPCODE();
 
1661
}
 
1662
 
 
1663
 
 
1664
static inline int zend_binary_assign_op_obj_helper(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
 
1665
{
 
1666
        zend_op *op_data = opline+1;
 
1667
        zval **object_ptr = get_obj_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 
1668
        zval *object;
 
1669
        zval *property = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
1670
        zval *free_value;
 
1671
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_value, BP_VAR_R);
 
1672
        znode *result = &opline->result;
 
1673
        zval **retval = &EX_T(result->u.var).var.ptr;
 
1674
        int have_get_ptr = 0;
 
1675
 
 
1676
        EX_T(result->u.var).var.ptr_ptr = NULL;
 
1677
        make_real_object(object_ptr TSRMLS_CC);
 
1678
        object = *object_ptr;
 
1679
        
 
1680
        if (object->type != IS_OBJECT) {
 
1681
                zend_error(E_WARNING, "Attempt to assign property of non-object");
 
1682
                FREE_OP(Ts, op2, EG(free_op2));
 
1683
                FREE_OP(Ts, value, free_value);
 
1684
 
 
1685
                *retval = EG(uninitialized_zval_ptr);
 
1686
 
 
1687
                SELECTIVE_PZVAL_LOCK(*retval, result);
 
1688
        } else {
 
1689
                /* here we are sure we are dealing with an object */
 
1690
                if (EG(free_op2)) {
 
1691
                        MAKE_REAL_ZVAL_PTR(property);
 
1692
                }
 
1693
 
 
1694
                /* here property is a string */
 
1695
                if (opline->extended_value == ZEND_ASSIGN_OBJ
 
1696
                        && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
 
1697
                        zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property TSRMLS_CC);
 
1698
                        if (zptr != NULL) {                     /* NULL means no success in getting PTR */
 
1699
                                SEPARATE_ZVAL_IF_NOT_REF(zptr);
 
1700
 
 
1701
                                have_get_ptr = 1;
 
1702
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
 
1703
                                *retval = *zptr;
 
1704
                                SELECTIVE_PZVAL_LOCK(*retval, result);
 
1705
                        }
 
1706
                }
 
1707
 
 
1708
                if (!have_get_ptr) {
 
1709
                        zval *z;
 
1710
                        
 
1711
                        switch (opline->extended_value) {
 
1712
                                case ZEND_ASSIGN_OBJ:
 
1713
                                        z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_RW TSRMLS_CC);
 
1714
                                        break;
 
1715
                                case ZEND_ASSIGN_DIM:
 
1716
                                        z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_RW TSRMLS_CC);
 
1717
                                        break;
 
1718
                        }
 
1719
                        if (z->type == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
 
1720
                                zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC);
 
1721
 
 
1722
                                if (z->refcount == 0) {
 
1723
                                        zval_dtor(z);
 
1724
                                        FREE_ZVAL(z);
 
1725
                                }
 
1726
                                z = value;
 
1727
                        }
 
1728
                        z->refcount++;
 
1729
                        SEPARATE_ZVAL_IF_NOT_REF(&z);
 
1730
                        binary_op(z, z, value TSRMLS_CC);
 
1731
                        switch (opline->extended_value) {
 
1732
                                case ZEND_ASSIGN_OBJ:
 
1733
                                        Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
 
1734
                                        break;
 
1735
                                case ZEND_ASSIGN_DIM:
 
1736
                                        Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
 
1737
                                        break;
 
1738
                        }
 
1739
                        *retval = z;
 
1740
                        SELECTIVE_PZVAL_LOCK(*retval, result);
 
1741
                        zval_ptr_dtor(&z);
 
1742
                }
 
1743
 
 
1744
                if (EG(free_op2)) {
 
1745
                        zval_ptr_dtor(&property);
 
1746
                }
 
1747
                FREE_OP(Ts, value, free_value);
 
1748
        }
 
1749
 
 
1750
        /* assign_obj has two opcodes! */
 
1751
        INC_OPCODE();
 
1752
        NEXT_OPCODE();
 
1753
}
 
1754
 
 
1755
 
 
1756
static inline int zend_binary_assign_op_helper(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
 
1757
{
 
1758
        zval **var_ptr;
 
1759
        zval *value;
 
1760
        zend_bool increment_opline = 0;
 
1761
 
 
1762
        switch (opline->extended_value) {
 
1763
                case ZEND_ASSIGN_OBJ:
 
1764
                        return zend_binary_assign_op_obj_helper(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1765
                        break;
 
1766
                case ZEND_ASSIGN_DIM: {
 
1767
                                zval **object_ptr = get_obj_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 
1768
 
 
1769
                                (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
 
1770
 
 
1771
                                if ((*object_ptr)->type == IS_OBJECT) {
 
1772
                                        return zend_binary_assign_op_obj_helper(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1773
                                } else {
 
1774
                                        zend_op *op_data = opline+1;
 
1775
 
 
1776
                                        zend_fetch_dimension_address(&op_data->op2, &opline->op1, &opline->op2, EX(Ts), BP_VAR_RW TSRMLS_CC);
 
1777
 
 
1778
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
1779
                                        var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), BP_VAR_RW);
 
1780
                                        EG(free_op2) = 0;
 
1781
                                        increment_opline = 1;
 
1782
                                }
 
1783
                        }
 
1784
                        break;
 
1785
                default:
 
1786
                        value = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
1787
                        var_ptr = get_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_RW);
 
1788
                        EG(free_op1) = 0;
 
1789
                        /* do nothing */
 
1790
                        break;
 
1791
        }
 
1792
 
 
1793
        if (!var_ptr) {
 
1794
                zend_error(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");
 
1795
        }
 
1796
 
 
1797
        if (*var_ptr == EG(error_zval_ptr)) {
 
1798
                EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
 
1799
                SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);
 
1800
                AI_USE_PTR(EX_T(opline->result.u.var).var);
 
1801
            if (increment_opline) {
 
1802
            INC_OPCODE();
 
1803
        }
 
1804
                NEXT_OPCODE();
 
1805
        }
 
1806
        
 
1807
        SEPARATE_ZVAL_IF_NOT_REF(var_ptr);
 
1808
 
 
1809
        if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
 
1810
           && Z_OBJ_HANDLER_PP(var_ptr, set)) {
 
1811
                /* proxy object */
 
1812
                zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
 
1813
                objval->refcount++;
 
1814
                binary_op(objval, objval, value TSRMLS_CC);
 
1815
                Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC);
 
1816
                zval_ptr_dtor(&objval);
 
1817
        } else {
 
1818
                binary_op(*var_ptr, *var_ptr, value TSRMLS_CC);
 
1819
        }
 
1820
        
 
1821
        EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
 
1822
        SELECTIVE_PZVAL_LOCK(*var_ptr, &opline->result);
 
1823
        FREE_OP(Ex(Ts), &opline->op1, EG(free_op1));
 
1824
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
1825
        AI_USE_PTR(EX_T(opline->result.u.var).var);
 
1826
 
 
1827
        if (increment_opline) {
 
1828
                INC_OPCODE();
 
1829
        }
 
1830
        NEXT_OPCODE();
 
1831
}
 
1832
 
 
1833
 
 
1834
int zend_assign_add_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1835
{
 
1836
        return zend_binary_assign_op_helper(add_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1837
}
 
1838
 
 
1839
 
 
1840
int zend_assign_sub_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1841
{
 
1842
        return zend_binary_assign_op_helper(sub_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1843
}
 
1844
 
 
1845
 
 
1846
int zend_assign_mul_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1847
{
 
1848
        return zend_binary_assign_op_helper(mul_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1849
}
 
1850
 
 
1851
 
 
1852
int zend_assign_div_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1853
{
 
1854
        return zend_binary_assign_op_helper(div_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1855
}
 
1856
 
 
1857
 
 
1858
int zend_assign_mod_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1859
{
 
1860
        return zend_binary_assign_op_helper(mod_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1861
}
 
1862
 
 
1863
 
 
1864
int zend_assign_sl_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1865
{
 
1866
        return zend_binary_assign_op_helper(shift_left_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1867
}
 
1868
 
 
1869
 
 
1870
int zend_assign_sr_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1871
{
 
1872
        return zend_binary_assign_op_helper(shift_right_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1873
}
 
1874
 
 
1875
 
 
1876
int zend_assign_concat_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1877
{
 
1878
        return zend_binary_assign_op_helper(concat_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1879
}
 
1880
 
 
1881
 
 
1882
int zend_assign_bw_or_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1883
{
 
1884
        return zend_binary_assign_op_helper(bitwise_or_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1885
}
 
1886
 
 
1887
 
 
1888
int zend_assign_bw_and_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1889
{
 
1890
        return zend_binary_assign_op_helper(bitwise_and_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1891
}
 
1892
 
 
1893
 
 
1894
int zend_assign_bw_xor_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1895
{
 
1896
        return zend_binary_assign_op_helper(bitwise_xor_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1897
}
 
1898
 
 
1899
int zend_pre_inc_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1900
{
 
1901
        zend_pre_incdec_property(&opline->result, &opline->op1, &opline->op2, EX(Ts), increment_function TSRMLS_CC);
 
1902
        NEXT_OPCODE();
 
1903
}
 
1904
 
 
1905
 
 
1906
int zend_pre_dec_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1907
{
 
1908
        zend_pre_incdec_property(&opline->result, &opline->op1, &opline->op2, EX(Ts), decrement_function TSRMLS_CC);
 
1909
        NEXT_OPCODE();
 
1910
}
 
1911
 
 
1912
 
 
1913
int zend_post_inc_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1914
{
 
1915
        zend_post_incdec_property(&opline->result, &opline->op1, &opline->op2, EX(Ts), increment_function TSRMLS_CC);
 
1916
        NEXT_OPCODE();
 
1917
}
 
1918
 
 
1919
 
 
1920
int zend_post_dec_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1921
{
 
1922
        zend_post_incdec_property(&opline->result, &opline->op1, &opline->op2, EX(Ts), decrement_function TSRMLS_CC);
 
1923
        NEXT_OPCODE();
 
1924
}
 
1925
 
 
1926
typedef int (*incdec_t)(zval *);
 
1927
 
 
1928
static inline int zend_incdec_op_helper(incdec_t incdec_op_arg, ZEND_OPCODE_HANDLER_ARGS)
 
1929
{
 
1930
        zval **var_ptr = get_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_RW);
 
1931
        int (*incdec_op)(zval *op1) = incdec_op_arg;
 
1932
 
 
1933
        if (!var_ptr) {
 
1934
                zend_error(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
 
1935
        }
 
1936
        if (*var_ptr == EG(error_zval_ptr)) {
 
1937
                switch (opline->opcode) {
 
1938
                        case ZEND_PRE_INC:
 
1939
                        case ZEND_PRE_DEC:
 
1940
                                EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
 
1941
                                SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);
 
1942
                                AI_USE_PTR(EX_T(opline->result.u.var).var);
 
1943
                                NEXT_OPCODE();
 
1944
                                break;
 
1945
                        case ZEND_POST_INC:
 
1946
                        case ZEND_POST_DEC:
 
1947
                                EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
 
1948
                                NEXT_OPCODE();
 
1949
                                break;
 
1950
                }
 
1951
        }
 
1952
 
 
1953
        switch (opline->opcode) {
 
1954
                case ZEND_POST_INC:
 
1955
                case ZEND_POST_DEC:
 
1956
                        EX_T(opline->result.u.var).tmp_var = **var_ptr;
 
1957
                        zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);
 
1958
                        break;
 
1959
        }
 
1960
        
 
1961
        SEPARATE_ZVAL_IF_NOT_REF(var_ptr);
 
1962
 
 
1963
        if(Z_TYPE_PP(var_ptr) == IS_OBJECT && Z_OBJ_HANDLER_PP(var_ptr, get)
 
1964
           && Z_OBJ_HANDLER_PP(var_ptr, set)) {
 
1965
                /* proxy object */
 
1966
                zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
 
1967
                val->refcount++;
 
1968
                incdec_op(val);
 
1969
                Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
 
1970
                zval_ptr_dtor(&val);
 
1971
        } else {
 
1972
                incdec_op(*var_ptr);
 
1973
        }
 
1974
 
 
1975
        switch (opline->opcode) {
 
1976
                case ZEND_PRE_INC:
 
1977
                case ZEND_PRE_DEC:
 
1978
                        EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
 
1979
                        SELECTIVE_PZVAL_LOCK(*var_ptr, &opline->result);
 
1980
                        AI_USE_PTR(EX_T(opline->result.u.var).var);
 
1981
                        break;
 
1982
        }
 
1983
        NEXT_OPCODE();
 
1984
}
 
1985
 
 
1986
 
 
1987
int zend_pre_inc_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1988
{
 
1989
        return zend_incdec_op_helper(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1990
}
 
1991
 
 
1992
 
 
1993
int zend_pre_dec_handler(ZEND_OPCODE_HANDLER_ARGS)
 
1994
{
 
1995
        return zend_incdec_op_helper(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
1996
}
 
1997
 
 
1998
 
 
1999
int zend_post_inc_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2000
{
 
2001
        return zend_incdec_op_helper(increment_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
2002
}
 
2003
 
 
2004
 
 
2005
int zend_post_dec_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2006
{
 
2007
        return zend_incdec_op_helper(decrement_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
2008
}
 
2009
 
 
2010
 
 
2011
int zend_echo_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2012
{
 
2013
        zval *free_op1;
 
2014
        zval z_copy;
 
2015
        zval *z = get_zval_ptr(&opline->op1, EX(Ts), &free_op1, BP_VAR_R);
 
2016
 
 
2017
        if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && 
 
2018
                zend_std_cast_object_tostring(z, &z_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) {
 
2019
                zend_print_variable(&z_copy);
 
2020
                zval_dtor(&z_copy);
 
2021
        } else {
 
2022
                zend_print_variable(z);
 
2023
        }
 
2024
 
 
2025
        FREE_OP(EX(Ts), &opline->op1, free_op1);
 
2026
        NEXT_OPCODE();
 
2027
}
 
2028
 
 
2029
 
 
2030
int zend_print_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2031
{
 
2032
        EX_T(opline->result.u.var).tmp_var.value.lval = 1;
 
2033
        EX_T(opline->result.u.var).tmp_var.type = IS_LONG;
 
2034
 
 
2035
        return zend_echo_handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
2036
}
 
2037
 
 
2038
 
 
2039
int zend_fetch_r_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2040
{
 
2041
        zend_fetch_var_address(opline, EX(Ts), BP_VAR_R TSRMLS_CC);
 
2042
        AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2043
        NEXT_OPCODE();
 
2044
}
 
2045
 
 
2046
 
 
2047
int zend_fetch_w_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2048
{
 
2049
        zend_fetch_var_address(opline, EX(Ts), BP_VAR_W TSRMLS_CC);
 
2050
        NEXT_OPCODE();
 
2051
}
 
2052
 
 
2053
 
 
2054
int zend_fetch_rw_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2055
{
 
2056
        zend_fetch_var_address(opline, EX(Ts), BP_VAR_RW TSRMLS_CC);
 
2057
        NEXT_OPCODE();
 
2058
}
 
2059
 
 
2060
 
 
2061
int zend_fetch_func_arg_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2062
{
 
2063
        if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
 
2064
                /* Behave like FETCH_W */
 
2065
                zend_fetch_var_address(opline, EX(Ts), BP_VAR_W TSRMLS_CC);
 
2066
        } else {
 
2067
                /* Behave like FETCH_R */
 
2068
                zend_fetch_var_address(opline, EX(Ts), BP_VAR_R TSRMLS_CC);
 
2069
                AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2070
        }
 
2071
        NEXT_OPCODE();
 
2072
}
 
2073
 
 
2074
 
 
2075
int zend_fetch_unset_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2076
{
 
2077
        zend_fetch_var_address(opline, EX(Ts), BP_VAR_R TSRMLS_CC);
 
2078
        PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
 
2079
        if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
 
2080
                SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
 
2081
        }
 
2082
        PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
 
2083
        NEXT_OPCODE();
 
2084
}
 
2085
 
 
2086
 
 
2087
int zend_fetch_is_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2088
{
 
2089
        zend_fetch_var_address(opline, EX(Ts), BP_VAR_IS TSRMLS_CC);
 
2090
        AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2091
        NEXT_OPCODE();
 
2092
}
 
2093
 
 
2094
 
 
2095
int zend_fetch_dim_r_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2096
{
 
2097
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
 
2098
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
 
2099
        }
 
2100
        zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
2101
        AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2102
        NEXT_OPCODE();
 
2103
}
 
2104
 
 
2105
 
 
2106
int zend_fetch_dim_w_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2107
{
 
2108
        zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC);
 
2109
        NEXT_OPCODE();
 
2110
}
 
2111
 
 
2112
 
 
2113
int zend_fetch_dim_rw_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2114
{
 
2115
        zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_RW TSRMLS_CC);
 
2116
        NEXT_OPCODE();
 
2117
}
 
2118
 
 
2119
 
 
2120
int zend_fetch_dim_is_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2121
{
 
2122
        zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_IS TSRMLS_CC);
 
2123
        AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2124
        NEXT_OPCODE();
 
2125
}
 
2126
 
 
2127
 
 
2128
int zend_fetch_dim_func_arg_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2129
{
 
2130
        if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
 
2131
                /* Behave like FETCH_DIM_W */
 
2132
                zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC);
 
2133
        } else {
 
2134
                if (opline->op2.op_type == IS_UNUSED) {
 
2135
                        zend_error(E_ERROR, "Cannot use [] for reading");
 
2136
                }
 
2137
                /* Behave like FETCH_DIM_R, except for locking used for list() */
 
2138
                zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
2139
                AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2140
        }
 
2141
        NEXT_OPCODE();
 
2142
}
 
2143
 
 
2144
 
 
2145
int zend_fetch_dim_unset_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2146
{
 
2147
        /* Not needed in DIM_UNSET
 
2148
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
 
2149
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
 
2150
        }
 
2151
        */
 
2152
        zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
 
2153
        if (EX_T(opline->result.u.var).var.ptr_ptr == NULL) {
 
2154
                zend_error(E_ERROR, "Cannot unset string offsets");
 
2155
        } else {
 
2156
                PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
 
2157
                if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
 
2158
                        SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
 
2159
                }
 
2160
                PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
 
2161
        }
 
2162
        NEXT_OPCODE();
 
2163
}
 
2164
 
 
2165
 
 
2166
int zend_fetch_obj_r_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2167
{
 
2168
        zend_fetch_property_address_read(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
2169
        AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2170
        NEXT_OPCODE();
 
2171
}
 
2172
 
 
2173
 
 
2174
int zend_fetch_obj_w_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2175
{
 
2176
        if (opline->extended_value == ZEND_FETCH_ADD_LOCK) {
 
2177
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
 
2178
                EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr;
 
2179
        }
 
2180
        zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC);
 
2181
        NEXT_OPCODE();
 
2182
}
 
2183
 
 
2184
 
 
2185
int zend_fetch_obj_rw_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2186
{
 
2187
        zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_RW TSRMLS_CC);
 
2188
        NEXT_OPCODE();
 
2189
}
 
2190
 
 
2191
 
 
2192
int zend_fetch_obj_is_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2193
{
 
2194
        zend_fetch_property_address_read(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_IS TSRMLS_CC);
 
2195
        AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2196
        NEXT_OPCODE();
 
2197
}
 
2198
 
 
2199
 
 
2200
int zend_fetch_obj_func_arg_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2201
{
 
2202
        if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
 
2203
                /* Behave like FETCH_OBJ_W */
 
2204
                zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC);
 
2205
        } else {
 
2206
                zend_fetch_property_address_read(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
2207
                AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2208
        }
 
2209
        NEXT_OPCODE();
 
2210
}
 
2211
 
 
2212
 
 
2213
int zend_fetch_obj_unset_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2214
{
 
2215
        zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
2216
 
 
2217
        PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
 
2218
        if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
 
2219
                SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
 
2220
        }
 
2221
        PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
 
2222
        NEXT_OPCODE();
 
2223
}
 
2224
 
 
2225
 
 
2226
int zend_fetch_dim_tmp_var_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2227
{
 
2228
        zend_fetch_dimension_address_from_tmp_var(&opline->result, &opline->op1, &opline->op2, EX(Ts) TSRMLS_CC);
 
2229
        AI_USE_PTR(EX_T(opline->result.u.var).var);
 
2230
        NEXT_OPCODE();
 
2231
}
 
2232
 
 
2233
 
 
2234
int zend_assign_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2235
{
 
2236
        zend_op *op_data = opline+1;
 
2237
        zval **object_ptr = get_obj_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 
2238
 
 
2239
        zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
 
2240
        /* assign_obj has two opcodes! */
 
2241
        INC_OPCODE();
 
2242
        NEXT_OPCODE();
 
2243
}
 
2244
 
 
2245
 
 
2246
int zend_assign_dim_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2247
{
 
2248
        zend_op *op_data = opline+1;
 
2249
        zval **object_ptr;
 
2250
        
 
2251
        if (EX_T(opline->op1.u.var).var.ptr_ptr) {
 
2252
                /* not an array offset */
 
2253
                object_ptr = get_obj_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 
2254
        } else {
 
2255
                object_ptr = NULL;
 
2256
        }
 
2257
 
 
2258
        if (object_ptr && (*object_ptr)->type == IS_OBJECT) {
 
2259
                zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
 
2260
        } else {
 
2261
                zval *value;
 
2262
 
 
2263
                if (object_ptr) {
 
2264
                        (*object_ptr)->refcount++;  /* undo the effect of get_obj_zval_ptr_ptr() */
 
2265
                }
 
2266
                zend_fetch_dimension_address(&op_data->op2, &opline->op1, &opline->op2, EX(Ts), BP_VAR_W TSRMLS_CC);
 
2267
 
 
2268
                value = get_zval_ptr(&op_data->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
2269
                zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (EG(free_op1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
 
2270
        }
 
2271
        /* assign_dim has two opcodes! */
 
2272
        INC_OPCODE();
 
2273
        NEXT_OPCODE();
 
2274
}
 
2275
 
 
2276
 
 
2277
int zend_assign_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2278
{
 
2279
        zval *value;
 
2280
        value = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
2281
 
 
2282
        zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (EG(free_op2)?IS_TMP_VAR:opline->op2.op_type), EX(Ts) TSRMLS_CC);
 
2283
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
2284
 
 
2285
        NEXT_OPCODE();
 
2286
}
 
2287
 
 
2288
 
 
2289
int zend_assign_ref_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2290
{
 
2291
        zval **value_ptr_ptr = get_zval_ptr_ptr(&opline->op2, EX(Ts), BP_VAR_W);
 
2292
 
 
2293
        if (opline->op2.op_type == IS_VAR &&
 
2294
            value_ptr_ptr &&
 
2295
            !(*value_ptr_ptr)->is_ref &&
 
2296
             opline->extended_value == ZEND_RETURNS_FUNCTION && 
 
2297
             !EX_T(opline->op2.u.var).var.fcall_returned_reference) {
 
2298
                PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
 
2299
                zend_error(E_STRICT, "Only variables should be assigned by reference");
 
2300
                return zend_assign_handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
2301
        }
 
2302
        if (opline->op1.op_type == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
 
2303
                zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
 
2304
        }
 
2305
 
 
2306
        zend_assign_to_variable_reference(&opline->result, get_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_W), value_ptr_ptr, EX(Ts) TSRMLS_CC);
 
2307
 
 
2308
        NEXT_OPCODE();
 
2309
}
 
2310
 
 
2311
 
 
2312
int zend_jmp_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2313
{
 
2314
#if DEBUG_ZEND>=2
 
2315
        printf("Jumping to %d\n", opline->op1.u.opline_num);
 
2316
#endif
 
2317
        SET_OPCODE(opline->op1.u.jmp_addr);
 
2318
        return 0; /* CHECK_ME */
 
2319
}
 
2320
 
 
2321
 
 
2322
int zend_jmpz_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2323
{
 
2324
        znode *op1 = &opline->op1;
 
2325
                                        
 
2326
        if (!i_zend_is_true(get_zval_ptr(op1, EX(Ts), &EG(free_op1), BP_VAR_R))) {
 
2327
#if DEBUG_ZEND>=2
 
2328
                printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
 
2329
#endif
 
2330
                SET_OPCODE(opline->op2.u.jmp_addr);
 
2331
                FREE_OP(EX(Ts), op1, EG(free_op1));
 
2332
                return 0; /* CHECK_ME */
 
2333
        }
 
2334
        FREE_OP(EX(Ts), op1, EG(free_op1));
 
2335
 
 
2336
        NEXT_OPCODE();
 
2337
}
 
2338
 
 
2339
 
 
2340
int zend_jmpnz_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2341
{
 
2342
        znode *op1 = &opline->op1;
 
2343
        
 
2344
        if (zend_is_true(get_zval_ptr(op1, EX(Ts), &EG(free_op1), BP_VAR_R))) {
 
2345
#if DEBUG_ZEND>=2
 
2346
                printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
 
2347
#endif
 
2348
                SET_OPCODE(opline->op2.u.jmp_addr);
 
2349
                FREE_OP(EX(Ts), op1, EG(free_op1));
 
2350
                return 0; /* CHECK_ME */
 
2351
        }
 
2352
        FREE_OP(EX(Ts), op1, EG(free_op1));
 
2353
 
 
2354
        NEXT_OPCODE();
 
2355
}
 
2356
 
 
2357
 
 
2358
int zend_jmpznz_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2359
{
 
2360
        znode *res = &opline->op1;
 
2361
        
 
2362
        if (zend_is_true(get_zval_ptr(res, EX(Ts), &EG(free_op1), BP_VAR_R))) {
 
2363
#if DEBUG_ZEND>=2
 
2364
                printf("Conditional jmp on true to %d\n", opline->extended_value);
 
2365
#endif
 
2366
                SET_OPCODE(&op_array->opcodes[opline->extended_value]);
 
2367
        } else {
 
2368
#if DEBUG_ZEND>=2
 
2369
                printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num);
 
2370
#endif
 
2371
                SET_OPCODE(&op_array->opcodes[opline->op2.u.opline_num]);
 
2372
        }
 
2373
        FREE_OP(EX(Ts), res, EG(free_op1));
 
2374
 
 
2375
        return 0; /* CHECK_ME */
 
2376
}
 
2377
 
 
2378
 
 
2379
int zend_jmpz_ex_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2380
{
 
2381
        zend_op *original_opline = opline;
 
2382
        int retval = zend_is_true(get_zval_ptr(&original_opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R));
 
2383
        
 
2384
        FREE_OP(EX(Ts), &original_opline->op1, EG(free_op1));
 
2385
        EX_T(original_opline->result.u.var).tmp_var.value.lval = retval;
 
2386
        EX_T(original_opline->result.u.var).tmp_var.type = IS_BOOL;
 
2387
        if (!retval) {
 
2388
#if DEBUG_ZEND>=2
 
2389
                printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
 
2390
#endif
 
2391
                SET_OPCODE(opline->op2.u.jmp_addr);
 
2392
                return 0; /* CHECK_ME */
 
2393
        }
 
2394
        NEXT_OPCODE();
 
2395
}
 
2396
 
 
2397
 
 
2398
int zend_jmpnz_ex_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2399
{
 
2400
        zend_op *original_opline = opline;
 
2401
        int retval = zend_is_true(get_zval_ptr(&original_opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R));
 
2402
        
 
2403
        FREE_OP(EX(Ts), &original_opline->op1, EG(free_op1));
 
2404
        EX_T(original_opline->result.u.var).tmp_var.value.lval = retval;
 
2405
        EX_T(original_opline->result.u.var).tmp_var.type = IS_BOOL;
 
2406
        if (retval) {
 
2407
#if DEBUG_ZEND>=2
 
2408
                printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
 
2409
#endif
 
2410
                SET_OPCODE(opline->op2.u.jmp_addr);
 
2411
                return 0; /* CHECK_ME */
 
2412
        }
 
2413
        NEXT_OPCODE();
 
2414
}
 
2415
 
 
2416
 
 
2417
int zend_free_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2418
{
 
2419
        zendi_zval_dtor(EX_T(opline->op1.u.var).tmp_var);
 
2420
        NEXT_OPCODE();
 
2421
}
 
2422
 
 
2423
 
 
2424
int zend_init_string_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2425
{
 
2426
        EX_T(opline->result.u.var).tmp_var.value.str.val = emalloc(1);
 
2427
        EX_T(opline->result.u.var).tmp_var.value.str.val[0] = 0;
 
2428
        EX_T(opline->result.u.var).tmp_var.value.str.len = 0;
 
2429
        EX_T(opline->result.u.var).tmp_var.refcount = 1;
 
2430
        EX_T(opline->result.u.var).tmp_var.type = IS_STRING;
 
2431
        EX_T(opline->result.u.var).tmp_var.is_ref = 0;
 
2432
        NEXT_OPCODE();
 
2433
}
 
2434
 
 
2435
 
 
2436
int zend_add_char_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2437
{
 
2438
        add_char_to_string(&EX_T(opline->result.u.var).tmp_var,
 
2439
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_NA),
 
2440
                &opline->op2.u.constant);
 
2441
        /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
 
2442
        NEXT_OPCODE();
 
2443
}
 
2444
 
 
2445
 
 
2446
int zend_add_string_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2447
{
 
2448
        add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
 
2449
                get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_NA),
 
2450
                &opline->op2.u.constant);
 
2451
        /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
 
2452
        NEXT_OPCODE();
 
2453
}
 
2454
 
 
2455
 
 
2456
int zend_add_var_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2457
{
 
2458
        zval *var = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
2459
        zval var_copy;
 
2460
        int use_copy;
 
2461
 
 
2462
        zend_make_printable_zval(var, &var_copy, &use_copy);
 
2463
        if (use_copy) {
 
2464
                var = &var_copy;
 
2465
        }
 
2466
        add_string_to_string(   &EX_T(opline->result.u.var).tmp_var,
 
2467
                                                        get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_NA),
 
2468
                                                        var);
 
2469
        if (use_copy) {
 
2470
                zval_dtor(var);
 
2471
        }
 
2472
        /* original comment, possibly problematic:
 
2473
         * FREE_OP is missing intentionally here - we're always working on the same temporary variable
 
2474
         * (Zeev):  I don't think it's problematic, we only use variables
 
2475
         * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're
 
2476
         * string offsets or overloaded objects
 
2477
         */
 
2478
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
2479
 
 
2480
        NEXT_OPCODE();
 
2481
}
 
2482
 
 
2483
 
 
2484
int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2485
{
 
2486
        zval *class_name;
 
2487
        
 
2488
 
 
2489
        if (opline->op2.op_type == IS_UNUSED) {
 
2490
                EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
 
2491
                NEXT_OPCODE();
 
2492
        }
 
2493
 
 
2494
        class_name = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
2495
 
 
2496
        switch (class_name->type) {
 
2497
                case IS_OBJECT:
 
2498
                        EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name);
 
2499
                        break;
 
2500
                case IS_STRING:
 
2501
                        EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
 
2502
                        break;
 
2503
                default:
 
2504
                        zend_error(E_ERROR, "Class name must be a valid object or a string");
 
2505
                        break;
 
2506
        }
 
2507
 
 
2508
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
2509
        NEXT_OPCODE();
 
2510
}
 
2511
 
 
2512
 
 
2513
int zend_init_ctor_call_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2514
{
 
2515
        zend_ptr_stack_n_push(&EG(arg_types_stack), 3, EX(fbc), EX(object), EX(calling_scope));
 
2516
 
 
2517
        if (opline->op1.op_type == IS_VAR) {
 
2518
                SELECTIVE_PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr, &opline->op1);
 
2519
        }
 
2520
 
 
2521
        /* We are not handling overloaded classes right now */
 
2522
        EX(object) = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
2523
 
 
2524
        /* New always returns the object as is_ref=0, therefore, we can just increment the reference count */
 
2525
        EX(object)->refcount++; /* For $this pointer */
 
2526
 
 
2527
        EX(fbc) = EX(fbc_constructor);
 
2528
 
 
2529
        if (EX(fbc)->type == ZEND_USER_FUNCTION) { /* HACK!! */
 
2530
                EX(calling_scope) = EX(fbc)->common.scope;
 
2531
        } else {
 
2532
                EX(calling_scope) = NULL;
 
2533
        }
 
2534
 
 
2535
        NEXT_OPCODE();
 
2536
}
 
2537
 
 
2538
 
 
2539
int zend_init_method_call_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2540
{
 
2541
        zval *function_name;
 
2542
        char *function_name_strval;
 
2543
        int function_name_strlen;
 
2544
        
 
2545
        zend_ptr_stack_n_push(&EG(arg_types_stack), 3, EX(fbc), EX(object), EX(calling_scope));
 
2546
 
 
2547
        function_name = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
2548
 
 
2549
        if (Z_TYPE_P(function_name)!=IS_STRING) {
 
2550
                zend_error(E_ERROR, "Method name must be a string");
 
2551
        }
 
2552
 
 
2553
        function_name_strval = function_name->value.str.val;
 
2554
        function_name_strlen = function_name->value.str.len;
 
2555
 
 
2556
        EX(calling_scope) = EG(scope);
 
2557
 
 
2558
        EX(object) = get_obj_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R TSRMLS_CC);
 
2559
                        
 
2560
        if (EX(object) && EX(object)->type == IS_OBJECT) {
 
2561
                if (Z_OBJ_HT_P(EX(object))->get_method == NULL) {
 
2562
                        zend_error(E_ERROR, "Object does not support method calls");
 
2563
                }
 
2564
 
 
2565
                /* First, locate the function. */
 
2566
                EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
 
2567
                if (!EX(fbc)) {
 
2568
                        zend_error(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
 
2569
                }
 
2570
        } else {
 
2571
                zend_error(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
 
2572
        }
 
2573
 
 
2574
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
 
2575
                EX(object) = NULL;
 
2576
        } else {
 
2577
                if (!PZVAL_IS_REF(EX(object))) {
 
2578
                        EX(object)->refcount++; /* For $this pointer */
 
2579
                } else {
 
2580
                        zval *this_ptr;
 
2581
                        ALLOC_ZVAL(this_ptr);
 
2582
                        *this_ptr = *EX(object);
 
2583
                        INIT_PZVAL(this_ptr);
 
2584
                        zval_copy_ctor(this_ptr);
 
2585
                        EX(object) = this_ptr;
 
2586
                }       
 
2587
        }
 
2588
 
 
2589
        if (EX(fbc)->type == ZEND_USER_FUNCTION) {
 
2590
                EX(calling_scope) = EX(fbc)->common.scope;
 
2591
        } else {
 
2592
                EX(calling_scope) = NULL;
 
2593
        }
 
2594
 
 
2595
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
2596
        
 
2597
        NEXT_OPCODE();
 
2598
}
 
2599
 
 
2600
 
 
2601
int zend_init_static_method_call_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2602
{
 
2603
        zval *function_name;
 
2604
        zend_class_entry *ce;
 
2605
 
 
2606
        zend_ptr_stack_n_push(&EG(arg_types_stack), 3, EX(fbc), EX(object), EX(calling_scope));
 
2607
 
 
2608
        ce = EX_T(opline->op1.u.var).class_entry;
 
2609
        if(opline->op2.op_type != IS_UNUSED) {
 
2610
                char *function_name_strval;
 
2611
                int function_name_strlen;
 
2612
                zend_bool is_const = (opline->op2.op_type == IS_CONST);
 
2613
 
 
2614
                if (is_const) {
 
2615
                        function_name_strval = opline->op2.u.constant.value.str.val;
 
2616
                        function_name_strlen = opline->op2.u.constant.value.str.len;
 
2617
                } else {
 
2618
                        function_name = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
2619
 
 
2620
                        if (Z_TYPE_P(function_name) != IS_STRING) {
 
2621
                                zend_error(E_ERROR, "Function name must be a string");
 
2622
                        }
 
2623
                        function_name_strval = zend_str_tolower_dup(function_name->value.str.val, function_name->value.str.len);
 
2624
                        function_name_strlen = function_name->value.str.len;
 
2625
                }
 
2626
 
 
2627
                EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
 
2628
 
 
2629
                if (!is_const) {
 
2630
                        efree(function_name_strval);
 
2631
                        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
2632
                }       
 
2633
        } else {
 
2634
                if(!ce->constructor) {
 
2635
                        zend_error(E_ERROR, "Can not call constructor");
 
2636
                }
 
2637
                EX(fbc) = ce->constructor;
 
2638
        }
 
2639
 
 
2640
        EX(calling_scope) = EX(fbc)->common.scope;
 
2641
 
 
2642
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
 
2643
                EX(object) = NULL;
 
2644
        } else {
 
2645
                if ((EX(object) = EG(This))) {
 
2646
                        EX(object)->refcount++;
 
2647
                }
 
2648
        }
 
2649
 
 
2650
        NEXT_OPCODE();
 
2651
}
 
2652
 
 
2653
int zend_init_fcall_by_name_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2654
{
 
2655
        zval *function_name;
 
2656
        zend_function *function;
 
2657
        zend_bool is_const;
 
2658
        char *function_name_strval, *lcname;
 
2659
        int function_name_strlen;
 
2660
 
 
2661
        zend_ptr_stack_n_push(&EG(arg_types_stack), 3, EX(fbc), EX(object), EX(calling_scope));
 
2662
 
 
2663
        is_const = (opline->op2.op_type == IS_CONST);
 
2664
 
 
2665
        if (is_const) {
 
2666
                function_name_strval = opline->op2.u.constant.value.str.val;
 
2667
                function_name_strlen = opline->op2.u.constant.value.str.len;
 
2668
        } else {
 
2669
                function_name = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
2670
 
 
2671
                if (Z_TYPE_P(function_name) != IS_STRING) {
 
2672
                        zend_error(E_ERROR, "Function name must be a string");
 
2673
                }
 
2674
                function_name_strval = function_name->value.str.val;
 
2675
                function_name_strlen = function_name->value.str.len;
 
2676
        }
 
2677
 
 
2678
        lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
 
2679
        if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
 
2680
                efree(lcname);
 
2681
                zend_error(E_ERROR, "Call to undefined function %s()", function_name_strval);
 
2682
        }
 
2683
 
 
2684
        efree(lcname);
 
2685
        if (!is_const) {
 
2686
                FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
2687
        } 
 
2688
 
 
2689
        EX(calling_scope) = function->common.scope;
 
2690
        EX(object) = NULL;
 
2691
        
 
2692
        EX(fbc) = function;
 
2693
 
 
2694
        NEXT_OPCODE();
 
2695
}
 
2696
 
 
2697
int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS)
 
2698
{
 
2699
        zval **original_return_value;
 
2700
        zend_class_entry *current_scope;
 
2701
        zval *current_this;
 
2702
        int return_value_used = RETURN_VALUE_USED(opline);
 
2703
        zend_bool should_change_scope;
 
2704
 
 
2705
        if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
 
2706
                zend_error(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
 
2707
                NEXT_OPCODE(); /* Never reached */
 
2708
        }
 
2709
 
 
2710
        zend_ptr_stack_n_push(&EG(argument_stack), 2, (void *) opline->extended_value, NULL);
 
2711
 
 
2712
        EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
2713
 
 
2714
        if (EX(function_state).function->type == ZEND_USER_FUNCTION
 
2715
                || EX(function_state).function->common.scope) {
 
2716
                should_change_scope = 1;
 
2717
                current_this = EG(This);
 
2718
                EG(This) = EX(object);
 
2719
                current_scope = EG(scope);
 
2720
                EG(scope) = EX(calling_scope);
 
2721
        } else {
 
2722
                should_change_scope = 0;
 
2723
        }
 
2724
 
 
2725
        EX_T(opline->result.u.var).var.fcall_returned_reference = 0;
 
2726
 
 
2727
        if (EX(function_state).function->common.scope) {
 
2728
                if (!EG(This) && !(EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
 
2729
                        int severity;
 
2730
                        char *severity_word;
 
2731
                        if (EX(function_state).function->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
 
2732
                                severity = E_STRICT;
 
2733
                                severity_word = "should not";
 
2734
                        } else {
 
2735
                                severity = E_ERROR;
 
2736
                                severity_word = "cannot";
 
2737
                        }
 
2738
                        zend_error(severity, "Non-static method %s::%s() %s be called statically", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name, severity_word);
 
2739
                }
 
2740
        }
 
2741
        if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {      
 
2742
                ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
2743
                INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));
 
2744
 
 
2745
                if (EX(function_state).function->common.arg_info) {
 
2746
                        zend_uint i=0;
 
2747
                        zval **p;
 
2748
                        ulong arg_count;
 
2749
 
 
2750
                        p = (zval **) EG(argument_stack).top_element-2;
 
2751
                        arg_count = (ulong) *p;
 
2752
 
 
2753
                        while (arg_count>0) {
 
2754
                                zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count) TSRMLS_CC);
 
2755
                                arg_count--;
 
2756
                        }
 
2757
                }
 
2758
                if (!zend_execute_internal) {
 
2759
                        /* saves one function call if zend_execute_internal is not used */
 
2760
                        ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
 
2761
                } else {
 
2762
                        zend_execute_internal(execute_data, return_value_used TSRMLS_CC);
 
2763
                }
 
2764
 
 
2765
                EG(current_execute_data) = execute_data;
 
2766
                EX_T(opline->result.u.var).var.ptr->is_ref = 0;
 
2767
                EX_T(opline->result.u.var).var.ptr->refcount = 1;
 
2768
                if (!return_value_used) {
 
2769
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
 
2770
                }
 
2771
        } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
 
2772
                HashTable *calling_symbol_table;
 
2773
 
 
2774
                EX_T(opline->result.u.var).var.ptr = NULL;
 
2775
                if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
 
2776
                        /*printf("Cache hit!  Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
 
2777
                        EX(function_state).function_symbol_table = *(EG(symtable_cache_ptr)--);
 
2778
                } else {
 
2779
                        ALLOC_HASHTABLE(EX(function_state).function_symbol_table);
 
2780
                        zend_hash_init(EX(function_state).function_symbol_table, 0, NULL, ZVAL_PTR_DTOR, 0);
 
2781
                        /*printf("Cache miss!  Initialized %x\n", function_state.function_symbol_table);*/
 
2782
                }
 
2783
                calling_symbol_table = EG(active_symbol_table);
 
2784
                EG(active_symbol_table) = EX(function_state).function_symbol_table;
 
2785
                original_return_value = EG(return_value_ptr_ptr);
 
2786
                EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
 
2787
                EG(active_op_array) = (zend_op_array *) EX(function_state).function;
 
2788
 
 
2789
                zend_execute(EG(active_op_array) TSRMLS_CC);
 
2790
                EX_T(opline->result.u.var).var.fcall_returned_reference = EG(active_op_array)->return_reference;
 
2791
 
 
2792
                if (return_value_used && !EX_T(opline->result.u.var).var.ptr) {
 
2793
                        if (!EG(exception)) {
 
2794
                                ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
2795
                                INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
 
2796
                        }
 
2797
                } else if (!return_value_used && EX_T(opline->result.u.var).var.ptr) {
 
2798
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
 
2799
                }
 
2800
 
 
2801
                EG(opline_ptr) = &EX(opline);
 
2802
                EG(active_op_array) = op_array;
 
2803
                EG(return_value_ptr_ptr)=original_return_value;
 
2804
                if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
 
2805
                        zend_hash_destroy(EX(function_state).function_symbol_table);
 
2806
                        FREE_HASHTABLE(EX(function_state).function_symbol_table);
 
2807
                } else {
 
2808
                        /* clean before putting into the cache, since clean
 
2809
                           could call dtors, which could use cached hash */
 
2810
                        zend_hash_clean(EX(function_state).function_symbol_table);
 
2811
                        *(++EG(symtable_cache_ptr)) = EX(function_state).function_symbol_table;
 
2812
                }
 
2813
                EG(active_symbol_table) = calling_symbol_table;
 
2814
        } else { /* ZEND_OVERLOADED_FUNCTION */
 
2815
                ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
2816
                INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));
 
2817
 
 
2818
                        /* Not sure what should be done here if it's a static method */
 
2819
                if (EX(object)) {
 
2820
                        Z_OBJ_HT_P(EX(object))->call_method(EX(fbc)->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
 
2821
                } else {
 
2822
                        zend_error(E_ERROR, "Cannot call overloaded function for non-object");
 
2823
                }
 
2824
                        
 
2825
                if (EX(function_state).function->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
 
2826
                        efree(EX(function_state).function->common.function_name);
 
2827
                }
 
2828
                efree(EX(fbc));
 
2829
 
 
2830
                if (!return_value_used) {
 
2831
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
 
2832
                } else {
 
2833
                        EX_T(opline->result.u.var).var.ptr->is_ref = 0;
 
2834
                        EX_T(opline->result.u.var).var.ptr->refcount = 1;
 
2835
                }
 
2836
        }
 
2837
 
 
2838
        if (EG(This)) {
 
2839
                if (EG(exception) && EX(fbc) && EX(fbc)->common.fn_flags&ZEND_ACC_CTOR) {
 
2840
                        EG(This)->refcount--;
 
2841
                        if (EG(This)->refcount == 1) {
 
2842
                                zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
 
2843
                        }
 
2844
                        if (should_change_scope && EG(This) != current_this) {
 
2845
                                zval_ptr_dtor(&EG(This));
 
2846
                        }
 
2847
                } else if (should_change_scope) {
 
2848
                        zval_ptr_dtor(&EG(This));
 
2849
                }
 
2850
        }
 
2851
 
 
2852
        if (should_change_scope) {
 
2853
                EG(This) = current_this;
 
2854
                EG(scope) = current_scope;
 
2855
        }
 
2856
        zend_ptr_stack_n_pop(&EG(arg_types_stack), 3, &EX(calling_scope), &EX(object), &EX(fbc));
 
2857
        
 
2858
        EX(function_state).function = (zend_function *) op_array;
 
2859
        EG(function_state_ptr) = &EX(function_state);
 
2860
        zend_ptr_stack_clear_multiple(TSRMLS_C);
 
2861
 
 
2862
        if (EG(exception)) {
 
2863
                zend_throw_exception_internal(NULL TSRMLS_CC);
 
2864
                if (return_value_used && EX_T(opline->result.u.var).var.ptr) {
 
2865
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
 
2866
                }
 
2867
        }
 
2868
 
 
2869
        NEXT_OPCODE();
 
2870
}
 
2871
 
 
2872
 
 
2873
int zend_do_fcall_by_name_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2874
{
 
2875
        EX(function_state).function = EX(fbc);
 
2876
        return zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
2877
}
 
2878
 
 
2879
 
 
2880
int zend_do_fcall_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2881
{
 
2882
        zval *fname = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
2883
        
 
2884
        zend_ptr_stack_n_push(&EG(arg_types_stack), 3, EX(fbc), EX(object), EX(calling_scope));
 
2885
 
 
2886
        if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
 
2887
                zend_error(E_ERROR, "Unknown function:  %s()\n", fname->value.str.val);
 
2888
        }
 
2889
        EX(object) = NULL;
 
2890
        EX(calling_scope) = EX(function_state).function->common.scope;
 
2891
 
 
2892
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
2893
                                        
 
2894
        return zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
2895
}
 
2896
 
 
2897
 
 
2898
int zend_return_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2899
{
 
2900
        zval *retval_ptr;
 
2901
        zval **retval_ptr_ptr;
 
2902
                        
 
2903
        if (EG(active_op_array)->return_reference == ZEND_RETURN_REF) {
 
2904
                if (opline->op1.op_type == IS_CONST || opline->op1.op_type == IS_TMP_VAR) {
 
2905
                        /* Not supposed to happen, but we'll allow it */
 
2906
                        zend_error(E_STRICT, "Only variable references should be returned by reference");
 
2907
                        goto return_by_value;
 
2908
                }
 
2909
 
 
2910
                retval_ptr_ptr = get_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_W);
 
2911
 
 
2912
                if (!retval_ptr_ptr) {
 
2913
                        zend_error(E_ERROR, "Cannot return string offsets by reference");
 
2914
                }
 
2915
 
 
2916
                if (!(*retval_ptr_ptr)->is_ref) {
 
2917
                        if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
 
2918
                            EX_T(opline->op1.u.var).var.fcall_returned_reference) {
 
2919
                        } else if (EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
 
2920
                                PZVAL_LOCK(*retval_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */
 
2921
                                zend_error(E_STRICT, "Only variable references should be returned by reference");
 
2922
                                goto return_by_value;
 
2923
                        }
 
2924
                }
 
2925
                
 
2926
                SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
 
2927
                (*retval_ptr_ptr)->refcount++;
 
2928
                
 
2929
                (*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
 
2930
        } else {
 
2931
return_by_value:
 
2932
                retval_ptr = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
2933
        
 
2934
                if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) {
 
2935
                        char *class_name;
 
2936
                        zend_uint class_name_len;
 
2937
                        int dup;
 
2938
 
 
2939
                        dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
 
2940
 
 
2941
                        ALLOC_ZVAL(*(EG(return_value_ptr_ptr)));
 
2942
                        **EG(return_value_ptr_ptr) = *retval_ptr;
 
2943
                        INIT_PZVAL(*EG(return_value_ptr_ptr));
 
2944
                        if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
 
2945
                                zend_error(E_ERROR, "Trying to clone an uncloneable object of class %s",  class_name);
 
2946
                        }
 
2947
                        zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
 
2948
                        (*EG(return_value_ptr_ptr))->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
 
2949
 
 
2950
                        if(!dup) {
 
2951
                           efree(class_name);
 
2952
                        }
 
2953
                } else if (!EG(free_op1)) { /* Not a temp var */
 
2954
                        if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
 
2955
                            (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) {
 
2956
                                ALLOC_ZVAL(*(EG(return_value_ptr_ptr)));
 
2957
                                **EG(return_value_ptr_ptr) = *retval_ptr;
 
2958
                                (*EG(return_value_ptr_ptr))->is_ref = 0;
 
2959
                                (*EG(return_value_ptr_ptr))->refcount = 1;
 
2960
                                zval_copy_ctor(*EG(return_value_ptr_ptr));
 
2961
                        } else {
 
2962
                                *EG(return_value_ptr_ptr) = retval_ptr;
 
2963
                                retval_ptr->refcount++;
 
2964
                        }
 
2965
                } else {
 
2966
                        ALLOC_ZVAL(*(EG(return_value_ptr_ptr)));
 
2967
                        **EG(return_value_ptr_ptr) = *retval_ptr;
 
2968
                        (*EG(return_value_ptr_ptr))->refcount = 1;
 
2969
                        (*EG(return_value_ptr_ptr))->is_ref = 0;
 
2970
                }
 
2971
        }
 
2972
        RETURN_FROM_EXECUTE_LOOP(execute_data);
 
2973
}
 
2974
 
 
2975
 
 
2976
int zend_throw_handler(ZEND_OPCODE_HANDLER_ARGS)
 
2977
{
 
2978
        zval *value;
 
2979
        zval *exception;
 
2980
 
 
2981
        value = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
2982
 
 
2983
        if (value->type != IS_OBJECT) {
 
2984
                zend_error(E_ERROR, "Can only throw objects");
 
2985
        }
 
2986
        /* Not sure if a complete copy is what we want here */
 
2987
        MAKE_STD_ZVAL(exception);
 
2988
        *exception = *value;
 
2989
        if (!EG(free_op1)) {
 
2990
                zval_copy_ctor(exception);
 
2991
        }
 
2992
        INIT_PZVAL(exception);
 
2993
 
 
2994
        zend_throw_exception_object(exception TSRMLS_CC);
 
2995
        NEXT_OPCODE();
 
2996
}
 
2997
 
 
2998
 
 
2999
int zend_catch_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3000
{
 
3001
        zend_class_entry *ce;
 
3002
 
 
3003
        /* Check whether an exception has been thrown, if not, jump over code */
 
3004
        if (EG(exception) == NULL) {
 
3005
                SET_OPCODE(&op_array->opcodes[opline->extended_value]);
 
3006
                return 0; /* CHECK_ME */
 
3007
        }
 
3008
        ce = Z_OBJCE_P(EG(exception));
 
3009
        if (ce != EX_T(opline->op1.u.var).class_entry) {
 
3010
                if (!instanceof_function(ce, EX_T(opline->op1.u.var).class_entry TSRMLS_CC)) {
 
3011
                        if (opline->op1.u.EA.type) {
 
3012
                                zend_throw_exception_internal(NULL TSRMLS_CC);
 
3013
                                NEXT_OPCODE();
 
3014
                        }
 
3015
                        SET_OPCODE(&op_array->opcodes[opline->extended_value]);
 
3016
                        return 0; /* CHECK_ME */
 
3017
                }
 
3018
        }
 
3019
 
 
3020
        zend_hash_update(EG(active_symbol_table), opline->op2.u.constant.value.str.val,
 
3021
                opline->op2.u.constant.value.str.len+1, &EG(exception), sizeof(zval *), (void **) NULL);
 
3022
        EG(exception) = NULL;
 
3023
        NEXT_OPCODE();
 
3024
}
 
3025
 
 
3026
 
 
3027
int zend_send_val_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3028
{
 
3029
        if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
 
3030
                && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
 
3031
                        zend_error(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
 
3032
        }
 
3033
        {
 
3034
                zval *valptr;
 
3035
                zval *value;
 
3036
 
 
3037
                value = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
3038
 
 
3039
                ALLOC_ZVAL(valptr);
 
3040
                *valptr = *value;
 
3041
                if (!EG(free_op1)) {
 
3042
                        zval_copy_ctor(valptr);
 
3043
                }
 
3044
                INIT_PZVAL(valptr);
 
3045
                zend_ptr_stack_push(&EG(argument_stack), valptr);
 
3046
        }
 
3047
        NEXT_OPCODE();
 
3048
}
 
3049
 
 
3050
 
 
3051
static inline int zend_send_by_var_helper(ZEND_OPCODE_HANDLER_ARGS)
 
3052
{
 
3053
        zval *varptr;
 
3054
        varptr = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
3055
 
 
3056
        if (varptr == &EG(uninitialized_zval)) {
 
3057
                ALLOC_ZVAL(varptr);
 
3058
                INIT_ZVAL(*varptr);
 
3059
                varptr->refcount = 0;
 
3060
        } else if (PZVAL_IS_REF(varptr)) {
 
3061
                zval *original_var = varptr;
 
3062
 
 
3063
                ALLOC_ZVAL(varptr);
 
3064
                *varptr = *original_var;
 
3065
                varptr->is_ref = 0;
 
3066
                varptr->refcount = 0;
 
3067
                zval_copy_ctor(varptr);
 
3068
        }
 
3069
        varptr->refcount++;
 
3070
        zend_ptr_stack_push(&EG(argument_stack), varptr);
 
3071
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));  /* for string offsets */
 
3072
 
 
3073
        NEXT_OPCODE();
 
3074
}
 
3075
 
 
3076
 
 
3077
int zend_send_var_no_ref_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3078
{
 
3079
        if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */
 
3080
                if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
 
3081
                        return zend_send_by_var_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
3082
                }
 
3083
        } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
 
3084
                return zend_send_by_var_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
3085
        }
 
3086
        if ((opline->extended_value & ZEND_ARG_SEND_FUNCTION) &&
 
3087
            !EX_T(opline->op1.u.var).var.fcall_returned_reference) {
 
3088
                zend_error(E_ERROR, "Only variables can be passed by reference");
 
3089
        } else {
 
3090
                zval *varptr;
 
3091
                varptr = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
3092
 
 
3093
                if (varptr != &EG(uninitialized_zval) && (PZVAL_IS_REF(varptr) || varptr->refcount == 1)) {
 
3094
                        varptr->is_ref = 1;
 
3095
                        varptr->refcount++;
 
3096
                        zend_ptr_stack_push(&EG(argument_stack), varptr);
 
3097
                        NEXT_OPCODE();
 
3098
                }
 
3099
                zend_error(E_ERROR, "Only variables can be passed by reference");
 
3100
        }
 
3101
        NEXT_OPCODE();
 
3102
}
 
3103
 
 
3104
 
 
3105
int zend_send_ref_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3106
{
 
3107
        zval **varptr_ptr;
 
3108
        zval *varptr;
 
3109
        varptr_ptr = get_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_W);
 
3110
 
 
3111
        if (!varptr_ptr) {
 
3112
                zend_error(E_ERROR, "Only variables can be passed by reference");
 
3113
        }
 
3114
 
 
3115
        SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr);
 
3116
        varptr = *varptr_ptr;
 
3117
        varptr->refcount++;
 
3118
        zend_ptr_stack_push(&EG(argument_stack), varptr);
 
3119
 
 
3120
        NEXT_OPCODE();
 
3121
}
 
3122
 
 
3123
 
 
3124
int zend_send_var_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3125
{
 
3126
        if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
 
3127
                && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
 
3128
                return zend_send_ref_handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
3129
        }
 
3130
        return zend_send_by_var_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
3131
}
 
3132
 
 
3133
 
 
3134
int zend_recv_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3135
{
 
3136
        zval **param;
 
3137
        zend_uint arg_num = opline->op1.u.constant.value.lval;
 
3138
 
 
3139
        if (zend_ptr_stack_get_arg(arg_num, (void **) &param TSRMLS_CC)==FAILURE) {
 
3140
                char *space;
 
3141
                char *class_name = get_active_class_name(&space TSRMLS_CC);
 
3142
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC);
 
3143
                zend_error(E_WARNING, "Missing argument %ld for %s%s%s()", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C));
 
3144
                if (opline->result.op_type == IS_VAR) {
 
3145
                        PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
 
3146
                }
 
3147
        } else {
 
3148
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param TSRMLS_CC);
 
3149
                if (PZVAL_IS_REF(*param)) {
 
3150
                        zend_assign_to_variable_reference(NULL, get_zval_ptr_ptr(&opline->result, EX(Ts), BP_VAR_W), param, NULL TSRMLS_CC);
 
3151
                } else {
 
3152
                        zend_assign_to_variable(NULL, &opline->result, NULL, *param, IS_VAR, EX(Ts) TSRMLS_CC);
 
3153
                }
 
3154
        }
 
3155
 
 
3156
        NEXT_OPCODE();
 
3157
}
 
3158
 
 
3159
 
 
3160
int zend_recv_init_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3161
{
 
3162
        zval **param, *assignment_value;
 
3163
        zend_uint arg_num = opline->op1.u.constant.value.lval;
 
3164
 
 
3165
        if (zend_ptr_stack_get_arg(arg_num, (void **) &param TSRMLS_CC)==FAILURE) {
 
3166
                if (opline->op2.u.constant.type == IS_CONSTANT || opline->op2.u.constant.type==IS_CONSTANT_ARRAY) {
 
3167
                        zval *default_value;
 
3168
 
 
3169
                        ALLOC_ZVAL(default_value);
 
3170
                        *default_value = opline->op2.u.constant;
 
3171
                        if (opline->op2.u.constant.type==IS_CONSTANT_ARRAY) {
 
3172
                                zval_copy_ctor(default_value);
 
3173
                        }
 
3174
                        default_value->refcount=1;
 
3175
                        zval_update_constant(&default_value, 0 TSRMLS_CC);
 
3176
                        default_value->refcount=0;
 
3177
                        default_value->is_ref=0;
 
3178
                        param = &default_value;
 
3179
                        assignment_value = default_value;
 
3180
                } else {
 
3181
                        param = NULL;
 
3182
                        assignment_value = &opline->op2.u.constant;
 
3183
                }
 
3184
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
 
3185
                zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
 
3186
        } else {
 
3187
                assignment_value = *param;
 
3188
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
 
3189
                if (PZVAL_IS_REF(assignment_value)) {
 
3190
                        zend_assign_to_variable_reference(NULL, get_zval_ptr_ptr(&opline->result, EX(Ts), BP_VAR_W), param, NULL TSRMLS_CC);
 
3191
                } else {
 
3192
                        zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
 
3193
                }
 
3194
        }
 
3195
 
 
3196
        NEXT_OPCODE();
 
3197
}
 
3198
 
 
3199
 
 
3200
int zend_bool_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3201
{
 
3202
        /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
 
3203
        EX_T(opline->result.u.var).tmp_var.value.lval = zend_is_true(get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R));
 
3204
        EX_T(opline->result.u.var).tmp_var.type = IS_BOOL;
 
3205
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
3206
 
 
3207
        NEXT_OPCODE();
 
3208
}
 
3209
 
 
3210
 
 
3211
static inline int zend_brk_cont_helper(ZEND_OPCODE_HANDLER_ARGS)
 
3212
{
 
3213
        zval *nest_levels_zval = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
3214
        zval tmp;
 
3215
        int array_offset, nest_levels, original_nest_levels;
 
3216
        zend_brk_cont_element *jmp_to;
 
3217
 
 
3218
        if (nest_levels_zval->type != IS_LONG) {
 
3219
                tmp = *nest_levels_zval;
 
3220
                zval_copy_ctor(&tmp);
 
3221
                convert_to_long(&tmp);
 
3222
                nest_levels = tmp.value.lval;
 
3223
        } else {
 
3224
                nest_levels = nest_levels_zval->value.lval;
 
3225
        }
 
3226
        original_nest_levels = nest_levels;
 
3227
        array_offset = opline->op1.u.opline_num;
 
3228
        do {
 
3229
                if (array_offset==-1) {
 
3230
                        zend_error(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
 
3231
                }
 
3232
                jmp_to = &op_array->brk_cont_array[array_offset];
 
3233
                if (nest_levels>1) {
 
3234
                        zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
 
3235
 
 
3236
                        switch (brk_opline->opcode) {
 
3237
                                case ZEND_SWITCH_FREE:
 
3238
                                        zend_switch_free(brk_opline, EX(Ts) TSRMLS_CC);
 
3239
                                        break;
 
3240
                                case ZEND_FREE:
 
3241
                                        zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
 
3242
                                        break;
 
3243
                        }
 
3244
                }
 
3245
                array_offset = jmp_to->parent;
 
3246
        } while (--nest_levels > 0);
 
3247
 
 
3248
        if (opline->opcode == ZEND_BRK) {
 
3249
                SET_OPCODE(op_array->opcodes+jmp_to->brk);
 
3250
        } else {
 
3251
                SET_OPCODE(op_array->opcodes+jmp_to->cont);
 
3252
        }
 
3253
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
3254
        return 0; /* CHECK_ME */
 
3255
}
 
3256
 
 
3257
 
 
3258
int zend_brk_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3259
{
 
3260
        return zend_brk_cont_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
3261
}
 
3262
 
 
3263
 
 
3264
int zend_cont_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3265
{
 
3266
        return zend_brk_cont_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
3267
}
 
3268
 
 
3269
 
 
3270
int zend_case_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3271
{
 
3272
        int switch_expr_is_overloaded=0;
 
3273
 
 
3274
        if (opline->op1.op_type==IS_VAR) {
 
3275
                if (EX_T(opline->op1.u.var).var.ptr_ptr) {
 
3276
                        PZVAL_LOCK(EX_T(opline->op1.u.var).var.ptr);
 
3277
                } else {
 
3278
                        switch_expr_is_overloaded = 1;
 
3279
                        EX_T(opline->op1.u.var).str_offset.str->refcount++;
 
3280
                }
 
3281
        }
 
3282
        is_equal_function(&EX_T(opline->result.u.var).tmp_var, 
 
3283
                                 get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R),
 
3284
                                 get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R) TSRMLS_CC);
 
3285
 
 
3286
        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
3287
        if (switch_expr_is_overloaded) {
 
3288
                /* We only free op1 if this is a string offset,
 
3289
                 * Since if it is a TMP_VAR, it'll be reused by
 
3290
                 * other CASE opcodes (whereas string offsets
 
3291
                 * are allocated at each get_zval_ptr())
 
3292
                 */
 
3293
                FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
3294
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
 
3295
                AI_USE_PTR(EX_T(opline->op1.u.var).var);
 
3296
        }
 
3297
        NEXT_OPCODE();
 
3298
}
 
3299
 
 
3300
 
 
3301
int zend_switch_free_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3302
{
 
3303
        zend_switch_free(opline, EX(Ts) TSRMLS_CC);
 
3304
        NEXT_OPCODE();
 
3305
}
 
3306
 
 
3307
 
 
3308
int zend_new_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3309
{
 
3310
        if (EX_T(opline->op1.u.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
 
3311
                char *class_type;
 
3312
 
 
3313
                if (EX_T(opline->op1.u.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) {
 
3314
                        class_type = "interface";
 
3315
                } else {
 
3316
                        class_type = "abstract class";
 
3317
                }
 
3318
                zend_error(E_ERROR, "Cannot instantiate %s %s", class_type,  EX_T(opline->op1.u.var).class_entry->name);
 
3319
        }
 
3320
        EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
3321
        ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
3322
        object_init_ex(EX_T(opline->result.u.var).var.ptr, EX_T(opline->op1.u.var).class_entry);
 
3323
        EX_T(opline->result.u.var).var.ptr->refcount=1;
 
3324
        EX_T(opline->result.u.var).var.ptr->is_ref=0;
 
3325
        
 
3326
        NEXT_OPCODE();
 
3327
}
 
3328
 
 
3329
 
 
3330
int zend_clone_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3331
{
 
3332
        zval *obj = get_obj_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R TSRMLS_CC);
 
3333
        zend_class_entry *ce;
 
3334
        zend_function *clone;
 
3335
        zend_object_clone_obj_t clone_call;
 
3336
 
 
3337
        if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
 
3338
                zend_error(E_WARNING, "__clone method called on non-object");
 
3339
                EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
 
3340
                EX_T(opline->result.u.var).var.ptr->refcount++;
 
3341
                NEXT_OPCODE();
 
3342
        } 
 
3343
 
 
3344
        ce = (Z_OBJ_HT_P(obj)->get_class_entry) ? Z_OBJCE_P(obj) : NULL;
 
3345
        clone = ce ? ce->clone : NULL;
 
3346
        clone_call =  Z_OBJ_HT_P(obj)->clone_obj;
 
3347
        if (!clone_call) {
 
3348
                zend_error(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name);
 
3349
                EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
 
3350
                EX_T(opline->result.u.var).var.ptr->refcount++;
 
3351
        }
 
3352
 
 
3353
        if (ce && clone) {
 
3354
                if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
 
3355
                        /* Ensure that if we're calling a private function, we're allowed to do so.
 
3356
                         */
 
3357
                        if (ce != EG(scope)) {
 
3358
                                zend_error(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
 
3359
                        }
 
3360
                } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
 
3361
                        /* Ensure that if we're calling a protected function, we're allowed to do so.
 
3362
                         */
 
3363
                        if (!zend_check_protected(clone->common.scope, EG(scope))) {
 
3364
                                zend_error(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
 
3365
                        }
 
3366
                }
 
3367
        }
 
3368
 
 
3369
        EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
3370
        ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
3371
        EX_T(opline->result.u.var).var.ptr->value.obj = clone_call(obj TSRMLS_CC);
 
3372
        if (EG(exception)) {
 
3373
                FREE_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
3374
        } else {
 
3375
                EX_T(opline->result.u.var).var.ptr->type = IS_OBJECT;
 
3376
                EX_T(opline->result.u.var).var.ptr->refcount=1;
 
3377
                EX_T(opline->result.u.var).var.ptr->is_ref=1;
 
3378
        }
 
3379
        NEXT_OPCODE();
 
3380
}
 
3381
 
 
3382
 
 
3383
int zend_fetch_constant_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3384
{
 
3385
        zend_class_entry *ce = NULL;
 
3386
        zval **value;
 
3387
 
 
3388
        if (opline->op1.op_type == IS_UNUSED) {
 
3389
/* This seems to be a reminant of namespaces
 
3390
                if (EG(scope)) {
 
3391
                        ce = EG(scope);
 
3392
                        if (zend_hash_find(&ce->constants_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
 
3393
                                zval_update_constant(value, (void *) 1 TSRMLS_CC);
 
3394
                                EX_T(opline->result.u.var).tmp_var = **value;
 
3395
                                zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
 
3396
                                NEXT_OPCODE();
 
3397
                        }
 
3398
                }
 
3399
*/
 
3400
                if (!zend_get_constant(opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
 
3401
                        zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
 
3402
                                                opline->op2.u.constant.value.str.val,
 
3403
                                                opline->op2.u.constant.value.str.val);
 
3404
                        EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;
 
3405
                        zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
 
3406
                }
 
3407
                NEXT_OPCODE();
 
3408
        }
 
3409
        
 
3410
        ce = EX_T(opline->op1.u.var).class_entry;
 
3411
        
 
3412
        if (zend_hash_find(&ce->constants_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
 
3413
                zval_update_constant(value, (void *) 1 TSRMLS_CC);
 
3414
                EX_T(opline->result.u.var).tmp_var = **value;
 
3415
                zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
 
3416
        } else {
 
3417
                zend_error(E_ERROR, "Undefined class constant '%s'", opline->op2.u.constant.value.str.val);
 
3418
        }
 
3419
 
 
3420
        NEXT_OPCODE();
 
3421
}
 
3422
 
 
3423
 
 
3424
static inline int zend_init_add_array_helper(ZEND_OPCODE_HANDLER_ARGS)
 
3425
{
 
3426
        zval *array_ptr = &EX_T(opline->result.u.var).tmp_var;
 
3427
        zval *expr_ptr, **expr_ptr_ptr = NULL;
 
3428
        zval *offset=get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
3429
 
 
3430
        if (opline->extended_value) {
 
3431
                expr_ptr_ptr=get_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_R);
 
3432
                expr_ptr = *expr_ptr_ptr;
 
3433
        } else {
 
3434
                expr_ptr=get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
3435
        }
 
3436
        
 
3437
        if (opline->opcode == ZEND_INIT_ARRAY) {
 
3438
                array_init(array_ptr);
 
3439
                if (!expr_ptr) {
 
3440
                        NEXT_OPCODE();
 
3441
                }
 
3442
        }
 
3443
        if (!opline->extended_value && EG(free_op1)) { /* temporary variable */
 
3444
                zval *new_expr;
 
3445
 
 
3446
                ALLOC_ZVAL(new_expr);
 
3447
                *new_expr = *expr_ptr;
 
3448
                expr_ptr = new_expr;
 
3449
                INIT_PZVAL(expr_ptr);
 
3450
        } else {
 
3451
                if (opline->extended_value) {
 
3452
                        SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr);
 
3453
                        expr_ptr = *expr_ptr_ptr;
 
3454
                        expr_ptr->refcount++;
 
3455
                } else if (PZVAL_IS_REF(expr_ptr)) {
 
3456
                        zval *new_expr;
 
3457
 
 
3458
                        ALLOC_ZVAL(new_expr);
 
3459
                        *new_expr = *expr_ptr;
 
3460
                        expr_ptr = new_expr;
 
3461
                        zendi_zval_copy_ctor(*expr_ptr);
 
3462
                        INIT_PZVAL(expr_ptr);
 
3463
                } else {
 
3464
                        expr_ptr->refcount++;
 
3465
                }
 
3466
        }
 
3467
        if (offset) {
 
3468
                switch (offset->type) {
 
3469
                        case IS_DOUBLE:
 
3470
                                zend_hash_index_update(array_ptr->value.ht, (long) offset->value.dval, &expr_ptr, sizeof(zval *), NULL);
 
3471
                                break;
 
3472
                        case IS_LONG:
 
3473
                        case IS_BOOL:
 
3474
                                zend_hash_index_update(array_ptr->value.ht, offset->value.lval, &expr_ptr, sizeof(zval *), NULL);
 
3475
                                break;
 
3476
                        case IS_STRING:
 
3477
                                zend_symtable_update(array_ptr->value.ht, offset->value.str.val, offset->value.str.len+1, &expr_ptr, sizeof(zval *), NULL);
 
3478
                                break;
 
3479
                        case IS_NULL:
 
3480
                                zend_hash_update(array_ptr->value.ht, "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
 
3481
                                break;
 
3482
                        default:
 
3483
                                zend_error(E_WARNING, "Illegal offset type");
 
3484
                                zval_ptr_dtor(&expr_ptr);
 
3485
                                /* do nothing */
 
3486
                                break;
 
3487
                }
 
3488
                FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
3489
        } else {
 
3490
                zend_hash_next_index_insert(array_ptr->value.ht, &expr_ptr, sizeof(zval *), NULL);
 
3491
        }
 
3492
        NEXT_OPCODE();
 
3493
}
 
3494
 
 
3495
 
 
3496
int zend_init_array_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3497
{
 
3498
        return zend_init_add_array_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
3499
}
 
3500
 
 
3501
 
 
3502
int zend_add_array_element_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3503
{
 
3504
        return zend_init_add_array_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
3505
}
 
3506
 
 
3507
 
 
3508
int zend_cast_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3509
{
 
3510
        zval *expr = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
3511
        zval *result = &EX_T(opline->result.u.var).tmp_var;
 
3512
 
 
3513
        *result = *expr;
 
3514
        if (!EG(free_op1)) {
 
3515
                zendi_zval_copy_ctor(*result);
 
3516
        }                                       
 
3517
        switch (opline->extended_value) {
 
3518
                case IS_NULL:
 
3519
                        convert_to_null(result);
 
3520
                        break;
 
3521
                case IS_BOOL:
 
3522
                        convert_to_boolean(result);
 
3523
                        break;
 
3524
                case IS_LONG:
 
3525
                        convert_to_long(result);
 
3526
                        break;
 
3527
                case IS_DOUBLE:
 
3528
                        convert_to_double(result);
 
3529
                        break;
 
3530
                case IS_STRING: {
 
3531
                        zval var_copy;
 
3532
                        int use_copy;
 
3533
                
 
3534
                        zend_make_printable_zval(result, &var_copy, &use_copy);
 
3535
                        if (use_copy) {
 
3536
                                zval_dtor(result);
 
3537
                                *result = var_copy;
 
3538
                        }
 
3539
                        break;
 
3540
                }
 
3541
                case IS_ARRAY:
 
3542
                        convert_to_array(result);
 
3543
                        break;
 
3544
                case IS_OBJECT:
 
3545
                        convert_to_object(result);
 
3546
                        break;
 
3547
        }
 
3548
        NEXT_OPCODE();
 
3549
}
 
3550
 
 
3551
 
 
3552
int zend_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3553
{
 
3554
        zend_op_array *new_op_array=NULL;
 
3555
        zval **original_return_value = EG(return_value_ptr_ptr);
 
3556
        int return_value_used;
 
3557
        zval *inc_filename = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
3558
        zval tmp_inc_filename;
 
3559
        zend_bool failure_retval=0;
 
3560
 
 
3561
        if (inc_filename->type!=IS_STRING) {
 
3562
                tmp_inc_filename = *inc_filename;
 
3563
                zval_copy_ctor(&tmp_inc_filename);
 
3564
                convert_to_string(&tmp_inc_filename);
 
3565
                inc_filename = &tmp_inc_filename;
 
3566
        }
 
3567
        
 
3568
        return_value_used = RETURN_VALUE_USED(opline);
 
3569
 
 
3570
        switch (opline->op2.u.constant.value.lval) {
 
3571
                case ZEND_INCLUDE_ONCE:
 
3572
                case ZEND_REQUIRE_ONCE: {
 
3573
                                int dummy = 1;
 
3574
                                zend_file_handle file_handle;
 
3575
 
 
3576
                                if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
 
3577
 
 
3578
                                        if (!file_handle.opened_path) {
 
3579
                                                file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
 
3580
                                        }       
 
3581
                                
 
3582
                                        if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
 
3583
                                                new_op_array = zend_compile_file(&file_handle, (opline->op2.u.constant.value.lval==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
 
3584
                                                zend_destroy_file_handle(&file_handle TSRMLS_CC);
 
3585
                                        } else {
 
3586
                                                zend_file_handle_dtor(&file_handle);
 
3587
                                                failure_retval=1;
 
3588
                                        }
 
3589
                                } else {
 
3590
                                        if (opline->op2.u.constant.value.lval==ZEND_INCLUDE_ONCE) {
 
3591
                                                zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, inc_filename->value.str.val);
 
3592
                                        } else {
 
3593
                                                zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, inc_filename->value.str.val);
 
3594
                                        }
 
3595
                                }
 
3596
                                break;
 
3597
                        }
 
3598
                        break;
 
3599
                case ZEND_INCLUDE:
 
3600
                case ZEND_REQUIRE:
 
3601
                        new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
 
3602
                        break;
 
3603
                case ZEND_EVAL: {
 
3604
                                char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
 
3605
 
 
3606
                                new_op_array = compile_string(inc_filename, eval_desc TSRMLS_CC);
 
3607
                                efree(eval_desc);
 
3608
                        }
 
3609
                        break;
 
3610
                EMPTY_SWITCH_DEFAULT_CASE()
 
3611
        }
 
3612
        if (inc_filename==&tmp_inc_filename) {
 
3613
                zval_dtor(&tmp_inc_filename);
 
3614
        }
 
3615
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
3616
        EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
3617
        if (new_op_array) {
 
3618
                zval *saved_object;
 
3619
                zend_function *saved_function;
 
3620
 
 
3621
                EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
 
3622
                EG(active_op_array) = new_op_array;
 
3623
                EX_T(opline->result.u.var).var.ptr = NULL;
 
3624
 
 
3625
                saved_object = EX(object);
 
3626
                saved_function = EX(function_state).function;
 
3627
 
 
3628
                EX(function_state).function = (zend_function *) new_op_array;
 
3629
                EX(object) = NULL;
 
3630
                
 
3631
                zend_execute(new_op_array TSRMLS_CC);
 
3632
                
 
3633
                EX(function_state).function = saved_function;
 
3634
                EX(object) = saved_object;
 
3635
                
 
3636
                if (!return_value_used) {
 
3637
                        if (EX_T(opline->result.u.var).var.ptr) {
 
3638
                                zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
 
3639
                        } 
 
3640
                } else { /* return value is used */
 
3641
                        if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
 
3642
                                ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
3643
                                INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
 
3644
                                EX_T(opline->result.u.var).var.ptr->value.lval = 1;
 
3645
                                EX_T(opline->result.u.var).var.ptr->type = IS_BOOL;
 
3646
                        }
 
3647
                }
 
3648
 
 
3649
                EG(opline_ptr) = &EX(opline);
 
3650
                EG(active_op_array) = op_array;
 
3651
                EG(function_state_ptr) = &EX(function_state);
 
3652
                destroy_op_array(new_op_array TSRMLS_CC);
 
3653
                efree(new_op_array);
 
3654
                if (EG(exception)) {
 
3655
                        zend_throw_exception_internal(NULL TSRMLS_CC);
 
3656
                }
 
3657
        } else {
 
3658
                if (return_value_used) {
 
3659
                        ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
3660
                        INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
 
3661
                        EX_T(opline->result.u.var).var.ptr->value.lval = failure_retval;
 
3662
                        EX_T(opline->result.u.var).var.ptr->type = IS_BOOL;
 
3663
                }
 
3664
        }
 
3665
        EG(return_value_ptr_ptr) = original_return_value;
 
3666
        NEXT_OPCODE();
 
3667
}
 
3668
 
 
3669
 
 
3670
int zend_unset_var_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3671
{
 
3672
        zval tmp, *varname;
 
3673
        HashTable *target_symbol_table;
 
3674
 
 
3675
        varname = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
3676
 
 
3677
        if (varname->type != IS_STRING) {
 
3678
                tmp = *varname;
 
3679
                zval_copy_ctor(&tmp);
 
3680
                convert_to_string(&tmp);
 
3681
                varname = &tmp;
 
3682
        }
 
3683
 
 
3684
        if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
 
3685
                zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
 
3686
        } else {
 
3687
                target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
 
3688
                zend_hash_del(target_symbol_table, varname->value.str.val, varname->value.str.len+1);
 
3689
        }
 
3690
 
 
3691
        if (varname == &tmp) {
 
3692
                zval_dtor(&tmp);
 
3693
        }
 
3694
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
3695
        NEXT_OPCODE();
 
3696
}
 
3697
 
 
3698
 
 
3699
 
 
3700
int zend_unset_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3701
{
 
3702
        zval **container = get_obj_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
 
3703
        zval *offset = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
3704
        long index;
 
3705
        
 
3706
        if (container) {
 
3707
                if (opline->extended_value == ZEND_UNSET_DIM) {
 
3708
                        switch (Z_TYPE_PP(container)) {
 
3709
                                case IS_ARRAY: {
 
3710
                                        HashTable *ht = Z_ARRVAL_PP(container);
 
3711
                                        switch (offset->type) {
 
3712
                                                case IS_DOUBLE:
 
3713
                                                case IS_RESOURCE:
 
3714
                                                case IS_BOOL: 
 
3715
                                                case IS_LONG:
 
3716
                                                        if (offset->type == IS_DOUBLE) {
 
3717
                                                                index = (long) offset->value.dval;
 
3718
                                                        } else {
 
3719
                                                                index = offset->value.lval;
 
3720
                                                        }
 
3721
        
 
3722
                                                        zend_hash_index_del(ht, index);
 
3723
                                                        break;
 
3724
                                                case IS_STRING:
 
3725
                                                        zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1);
 
3726
                                                        break;
 
3727
                                                case IS_NULL:
 
3728
                                                        zend_hash_del(ht, "", sizeof(""));
 
3729
                                                        break;
 
3730
                                                default: 
 
3731
                                                        zend_error(E_WARNING, "Illegal offset type in unset");
 
3732
                                                        break;
 
3733
                                        }
 
3734
                                        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
3735
                                        break;
 
3736
                                }
 
3737
                                case IS_OBJECT:
 
3738
                                        if (!Z_OBJ_HT_P(*container)->unset_dimension) {
 
3739
                                                zend_error(E_ERROR, "Cannot use object as array");
 
3740
                                        }
 
3741
                                        if (EG(free_op2)) {
 
3742
                                                MAKE_REAL_ZVAL_PTR(offset);
 
3743
                                        }
 
3744
                                        Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC);
 
3745
                                        if (EG(free_op2)) {
 
3746
                                                zval_ptr_dtor(&offset);
 
3747
                                        }
 
3748
                                        break;
 
3749
                                case IS_STRING:
 
3750
                                        zend_error(E_ERROR, "Cannot unset string offsets");
 
3751
                                        return 0; /* bailed out before */
 
3752
                                default:
 
3753
                                        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
3754
                                        break;
 
3755
                        }
 
3756
                } else { /* ZEND_UNSET_OBJ */
 
3757
                        if (Z_TYPE_PP(container) == IS_OBJECT) {
 
3758
                                if (EG(free_op2)) {
 
3759
                                        MAKE_REAL_ZVAL_PTR(offset);
 
3760
                                }
 
3761
                                Z_OBJ_HT_P(*container)->unset_property(*container, offset TSRMLS_CC);
 
3762
                                if (EG(free_op2)) {
 
3763
                                        zval_ptr_dtor(&offset);
 
3764
                                }
 
3765
                        }
 
3766
                }
 
3767
        } else {
 
3768
                /* overloaded element */
 
3769
                FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
3770
        }
 
3771
 
 
3772
        NEXT_OPCODE();
 
3773
}
 
3774
 
 
3775
 
 
3776
int zend_fe_reset_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3777
{
 
3778
        zval *array_ptr, **array_ptr_ptr;
 
3779
        HashTable *fe_ht;
 
3780
        zend_object_iterator *iter = NULL;
 
3781
        zend_class_entry *ce = NULL;
 
3782
        
 
3783
        if (opline->extended_value) {
 
3784
                array_ptr_ptr = get_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_R);
 
3785
                if (array_ptr_ptr == NULL) {
 
3786
                        ALLOC_INIT_ZVAL(array_ptr);
 
3787
                } else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) {
 
3788
                        if(Z_OBJ_HT_PP(array_ptr_ptr)->get_class_entry == NULL) {
 
3789
                                zend_error(E_WARNING, "foreach() can not iterate over objects without PHP class");
 
3790
                                opline++;
 
3791
                                SET_OPCODE(op_array->opcodes+opline->op2.u.opline_num);
 
3792
                                return 0;       
 
3793
                        }
 
3794
                        ce = Z_OBJCE_PP(array_ptr_ptr);
 
3795
                        if (!ce || ce->get_iterator == NULL) {
 
3796
                                SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
 
3797
                                (*array_ptr_ptr)->refcount++;
 
3798
                        }
 
3799
                        array_ptr = *array_ptr_ptr;
 
3800
                } else {
 
3801
                        SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr);
 
3802
                        array_ptr = *array_ptr_ptr;
 
3803
                        array_ptr->refcount++;
 
3804
                }
 
3805
        } else {
 
3806
                array_ptr = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
3807
                if (EG(free_op1)) { /* IS_TMP_VAR */
 
3808
                        zval *tmp;
 
3809
 
 
3810
                        ALLOC_ZVAL(tmp);
 
3811
                        *tmp = *array_ptr;
 
3812
                        INIT_PZVAL(tmp);
 
3813
                        array_ptr = tmp;
 
3814
                } else if (Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJ_HT_P(array_ptr)->get_class_entry) {
 
3815
                        ce = Z_OBJCE_P(array_ptr);
 
3816
                } else {
 
3817
                        array_ptr->refcount++;
 
3818
                }
 
3819
        }
 
3820
 
 
3821
        if (ce && ce->get_iterator) {
 
3822
                iter = ce->get_iterator(ce, array_ptr TSRMLS_CC);
 
3823
 
 
3824
                if (iter && !EG(exception)) {
 
3825
                        array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
 
3826
                } else {
 
3827
                        FREE_OP(Ts, op1, EG(free_op1));
 
3828
                        if (!EG(exception)) {
 
3829
                                zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name);
 
3830
                        }
 
3831
                        zend_throw_exception_internal(NULL TSRMLS_CC);
 
3832
                        NEXT_OPCODE();
 
3833
                        return 0;
 
3834
                }
 
3835
        }
 
3836
        
 
3837
        PZVAL_LOCK(array_ptr);
 
3838
        EX_T(opline->result.u.var).var.ptr = array_ptr;
 
3839
        EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;   
 
3840
 
 
3841
        if (iter) {
 
3842
                iter->index = 0;
 
3843
                if (iter->funcs->rewind) {
 
3844
                        iter->funcs->rewind(iter TSRMLS_CC);
 
3845
                        if (EG(exception)) {
 
3846
                                array_ptr->refcount--;
 
3847
                                zval_ptr_dtor(&array_ptr);
 
3848
                                NEXT_OPCODE();
 
3849
                        }
 
3850
                }
 
3851
        } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
 
3852
                /* probably redundant */
 
3853
                zend_hash_internal_pointer_reset(fe_ht);
 
3854
        } else {
 
3855
                zend_error(E_WARNING, "Invalid argument supplied for foreach()");
 
3856
                
 
3857
                opline++;
 
3858
                SET_OPCODE(op_array->opcodes+opline->op2.u.opline_num);
 
3859
                return 0;
 
3860
        }
 
3861
 
 
3862
        NEXT_OPCODE();
 
3863
}
 
3864
 
 
3865
 
 
3866
int zend_fe_fetch_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3867
{
 
3868
        zval *array = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
3869
        zval *result = &EX_T(opline->result.u.var).tmp_var;
 
3870
        zval **value, *key;
 
3871
        char *str_key;
 
3872
        uint str_key_len;
 
3873
        ulong int_key;
 
3874
        HashTable *fe_ht;
 
3875
        zend_object_iterator *iter = NULL;
 
3876
        int key_type;
 
3877
 
 
3878
        PZVAL_LOCK(array);
 
3879
 
 
3880
        switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) {
 
3881
                default:
 
3882
                case ZEND_ITER_INVALID:
 
3883
                        zend_error(E_WARNING, "Invalid argument supplied for foreach()");
 
3884
                        SET_OPCODE(op_array->opcodes+opline->op2.u.opline_num);
 
3885
                        return 0; /* CHECK_ME */
 
3886
                        
 
3887
                case ZEND_ITER_PLAIN_OBJECT: {
 
3888
                        char *class_name, *prop_name;
 
3889
                        zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);
 
3890
 
 
3891
                        fe_ht = HASH_OF(array);
 
3892
                        do {
 
3893
                                if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
 
3894
                                        /* reached end of iteration */
 
3895
                                        SET_OPCODE(op_array->opcodes+opline->op2.u.opline_num);
 
3896
                                        return 0; /* CHECK_ME */
 
3897
                                }
 
3898
                                key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
 
3899
 
 
3900
                                zend_hash_move_forward(fe_ht);
 
3901
                        } while (key_type != HASH_KEY_IS_STRING || zend_check_property_access(zobj, str_key TSRMLS_CC) != SUCCESS);
 
3902
                        zend_unmangle_property_name(str_key, &class_name, &prop_name);
 
3903
                        str_key_len = strlen(prop_name);
 
3904
                        str_key = estrndup(prop_name, str_key_len);
 
3905
                        str_key_len++;
 
3906
                        break;
 
3907
                }
 
3908
 
 
3909
                case ZEND_ITER_PLAIN_ARRAY:
 
3910
                        fe_ht = HASH_OF(array);
 
3911
                        if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) {
 
3912
                                /* reached end of iteration */
 
3913
                                SET_OPCODE(op_array->opcodes+opline->op2.u.opline_num);
 
3914
                                return 0; /* CHECK_ME */
 
3915
                        }
 
3916
                        key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
 
3917
                        zend_hash_move_forward(fe_ht);
 
3918
                        break;
 
3919
 
 
3920
                case ZEND_ITER_OBJECT:
 
3921
                        /* !iter happens from exception */
 
3922
                        if (iter && iter->index++) {
 
3923
                                /* This could cause an endless loop if index becomes zero again.
 
3924
                                 * In case that ever happens we need an additional flag. */
 
3925
                                iter->funcs->move_forward(iter TSRMLS_CC);
 
3926
                                if (EG(exception)) {
 
3927
                                        array->refcount--;
 
3928
                                        zval_ptr_dtor(&array);
 
3929
                                        NEXT_OPCODE();
 
3930
                                }
 
3931
                        }
 
3932
                        if (!iter || iter->funcs->valid(iter TSRMLS_CC) == FAILURE) {
 
3933
                                /* reached end of iteration */
 
3934
                                if (EG(exception)) {
 
3935
                                        array->refcount--;
 
3936
                                        zval_ptr_dtor(&array);
 
3937
                                        NEXT_OPCODE();
 
3938
                                }
 
3939
                                SET_OPCODE(op_array->opcodes+opline->op2.u.opline_num);
 
3940
                                return 0; /* CHECK_ME */
 
3941
                        }       
 
3942
                        iter->funcs->get_current_data(iter, &value TSRMLS_CC);
 
3943
                        if (EG(exception)) {
 
3944
                                array->refcount--;
 
3945
                                zval_ptr_dtor(&array);
 
3946
                                NEXT_OPCODE();
 
3947
                        }
 
3948
                        if (!value) {
 
3949
                                /* failure in get_current_data */
 
3950
                                SET_OPCODE(op_array->opcodes+opline->op2.u.opline_num);
 
3951
                                return 0; /* CHECK_ME */
 
3952
                        }
 
3953
                        if (iter->funcs->get_current_key) {
 
3954
                                key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
 
3955
                                if (EG(exception)) {
 
3956
                                        array->refcount--;
 
3957
                                        zval_ptr_dtor(&array);
 
3958
                                        NEXT_OPCODE();
 
3959
                                }
 
3960
                        } else {
 
3961
                                key_type = HASH_KEY_IS_LONG;
 
3962
                                int_key = iter->index;
 
3963
                        }
 
3964
 
 
3965
                        break;
 
3966
        }
 
3967
 
 
3968
        array_init(result);
 
3969
 
 
3970
        if (opline->extended_value) {
 
3971
                SEPARATE_ZVAL_IF_NOT_REF(value);
 
3972
                (*value)->is_ref = 1;
 
3973
        }
 
3974
        (*value)->refcount++;
 
3975
        zend_hash_index_update(result->value.ht, 0, value, sizeof(zval *), NULL);
 
3976
 
 
3977
        ALLOC_ZVAL(key);
 
3978
        INIT_PZVAL(key);
 
3979
 
 
3980
        switch (key_type) {
 
3981
                case HASH_KEY_IS_STRING:
 
3982
                        key->value.str.val = str_key;
 
3983
                        key->value.str.len = str_key_len-1;
 
3984
                        key->type = IS_STRING;
 
3985
                        break;
 
3986
                case HASH_KEY_IS_LONG:
 
3987
                        key->value.lval = int_key;
 
3988
                        key->type = IS_LONG;
 
3989
                        break;
 
3990
                EMPTY_SWITCH_DEFAULT_CASE()
 
3991
        }
 
3992
        zend_hash_index_update(result->value.ht, 1, &key, sizeof(zval *), NULL);
 
3993
 
 
3994
        NEXT_OPCODE();
 
3995
}
 
3996
 
 
3997
 
 
3998
int zend_jmp_no_ctor_handler(ZEND_OPCODE_HANDLER_ARGS)
 
3999
{
 
4000
        zval *object_zval;
 
4001
        zend_function *constructor;
 
4002
 
 
4003
        if (opline->op1.op_type == IS_VAR) {
 
4004
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
 
4005
        }
 
4006
        
 
4007
        object_zval = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
4008
        constructor = Z_OBJ_HT_P(object_zval)->get_constructor(object_zval TSRMLS_CC);
 
4009
 
 
4010
        EX(fbc_constructor) = NULL;
 
4011
        if (constructor == NULL) {
 
4012
                if(opline->op1.u.EA.type & EXT_TYPE_UNUSED) {
 
4013
                        zval_ptr_dtor(EX_T(opline->op1.u.var).var.ptr_ptr);
 
4014
                }
 
4015
                SET_OPCODE(op_array->opcodes + opline->op2.u.opline_num);
 
4016
                return 0; /* CHECK_ME */
 
4017
        } else {
 
4018
                EX(fbc_constructor) = constructor;
 
4019
        }
 
4020
 
 
4021
        NEXT_OPCODE();  
 
4022
}
 
4023
 
 
4024
 
 
4025
int zend_isset_isempty_var_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4026
{
 
4027
        zval tmp, *varname = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
4028
        zval **value;
 
4029
        zend_bool isset = 1;
 
4030
        HashTable *target_symbol_table;
 
4031
 
 
4032
        if (varname->type != IS_STRING) {
 
4033
                tmp = *varname;
 
4034
                zval_copy_ctor(&tmp);
 
4035
                convert_to_string(&tmp);
 
4036
                varname = &tmp;
 
4037
        }
 
4038
        
 
4039
        if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
 
4040
                value = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
 
4041
                if (!value) {
 
4042
                        isset = 0;
 
4043
                }
 
4044
        } else {
 
4045
                target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
 
4046
                if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
 
4047
                        isset = 0;
 
4048
                }
 
4049
        }
 
4050
        
 
4051
        EX_T(opline->result.u.var).tmp_var.type = IS_BOOL;
 
4052
 
 
4053
        switch (opline->extended_value) {
 
4054
                case ZEND_ISSET:
 
4055
                        if (isset && Z_TYPE_PP(value) == IS_NULL) {
 
4056
                                EX_T(opline->result.u.var).tmp_var.value.lval = 0;
 
4057
                        } else {
 
4058
                                EX_T(opline->result.u.var).tmp_var.value.lval = isset;
 
4059
                        }
 
4060
                        break;
 
4061
                case ZEND_ISEMPTY:
 
4062
                        if (!isset || !zend_is_true(*value)) {
 
4063
                                EX_T(opline->result.u.var).tmp_var.value.lval = 1;
 
4064
                        } else {
 
4065
                                EX_T(opline->result.u.var).tmp_var.value.lval = 0;
 
4066
                        }
 
4067
                        break;
 
4068
        }
 
4069
 
 
4070
        if (varname == &tmp) {
 
4071
                zval_dtor(&tmp);
 
4072
        }
 
4073
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
4074
 
 
4075
        NEXT_OPCODE();
 
4076
}
 
4077
 
 
4078
 
 
4079
static int zend_isset_isempty_dim_prop_obj_handler(int prop_dim, ZEND_OPCODE_HANDLER_ARGS)
 
4080
{
 
4081
        zval **container = get_obj_zval_ptr_ptr(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
 
4082
        zval **value = NULL;
 
4083
        int result = 0;
 
4084
        long index;
 
4085
 
 
4086
        if (container) {
 
4087
                zval *offset = get_zval_ptr(&opline->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
4088
 
 
4089
                if ((*container)->type == IS_ARRAY) {
 
4090
                        HashTable *ht;
 
4091
                        int isset = 0;
 
4092
 
 
4093
                        ht = (*container)->value.ht;
 
4094
 
 
4095
                        switch (offset->type) {
 
4096
                                case IS_DOUBLE:
 
4097
                                case IS_RESOURCE:
 
4098
                                case IS_BOOL: 
 
4099
                                case IS_LONG:
 
4100
                                        if (offset->type == IS_DOUBLE) {
 
4101
                                                index = (long) offset->value.dval;
 
4102
                                        } else {
 
4103
                                                index = offset->value.lval;
 
4104
                                        }
 
4105
                                        if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) {
 
4106
                                                isset = 1;
 
4107
                                        }
 
4108
                                        break;
 
4109
                                case IS_STRING:
 
4110
                                        if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
 
4111
                                                isset = 1;
 
4112
                                        }
 
4113
                                        break;
 
4114
                                case IS_NULL:
 
4115
                                        if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
 
4116
                                                isset = 1;
 
4117
                                        }
 
4118
                                        break;
 
4119
                                default: 
 
4120
                                        zend_error(E_WARNING, "Illegal offset type in unset");
 
4121
                                        
 
4122
                                        break;
 
4123
                        }
 
4124
                        
 
4125
                        switch (opline->extended_value) {
 
4126
                                case ZEND_ISSET:
 
4127
                                        if (isset && Z_TYPE_PP(value) == IS_NULL) {
 
4128
                                                result = 0;
 
4129
                                        } else {
 
4130
                                                result = isset;
 
4131
                                        }
 
4132
                                        break;
 
4133
                                case ZEND_ISEMPTY:
 
4134
                                        if (!isset || !zend_is_true(*value)) {
 
4135
                                                result = 0;
 
4136
                                        } else {
 
4137
                                                result = 1;
 
4138
                                        }
 
4139
                                        break;
 
4140
                        }
 
4141
                        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
4142
                } else if ((*container)->type == IS_OBJECT) {
 
4143
                        if (EG(free_op2)) {
 
4144
                                MAKE_REAL_ZVAL_PTR(offset);
 
4145
                        }
 
4146
                        if (prop_dim) {
 
4147
                                result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
 
4148
                        } else {
 
4149
                                result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value == ZEND_ISEMPTY) TSRMLS_CC);
 
4150
                        }
 
4151
                        if (EG(free_op2)) {
 
4152
                                zval_ptr_dtor(&offset);
 
4153
                        }       
 
4154
                } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
 
4155
                        zval tmp;
 
4156
 
 
4157
                        if (offset->type != IS_LONG) {
 
4158
                                tmp = *offset;
 
4159
                                zval_copy_ctor(&tmp);
 
4160
                                convert_to_long(&tmp);
 
4161
                                offset = &tmp;
 
4162
                        }
 
4163
                        switch (opline->extended_value) {
 
4164
                                case ZEND_ISSET:
 
4165
                                        if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
 
4166
                                                result = 1;
 
4167
                                        }
 
4168
                                        break;
 
4169
                                case ZEND_ISEMPTY:
 
4170
                                        if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
 
4171
                                                result = 1;
 
4172
                                        }
 
4173
                                        break;
 
4174
                        }
 
4175
                        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
4176
                } else {
 
4177
                        FREE_OP(EX(Ts), &opline->op2, EG(free_op2));
 
4178
                }
 
4179
        }
 
4180
 
 
4181
        EX_T(opline->result.u.var).tmp_var.type = IS_BOOL;
 
4182
 
 
4183
        switch (opline->extended_value) {
 
4184
                case ZEND_ISSET:
 
4185
                        EX_T(opline->result.u.var).tmp_var.value.lval = result;
 
4186
                        break;
 
4187
                case ZEND_ISEMPTY:
 
4188
                        EX_T(opline->result.u.var).tmp_var.value.lval = !result;
 
4189
                        break;
 
4190
        }
 
4191
 
 
4192
        NEXT_OPCODE();
 
4193
}
 
4194
 
 
4195
 
 
4196
int zend_isset_isempty_dim_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4197
{
 
4198
        return zend_isset_isempty_dim_prop_obj_handler(0, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
4199
}
 
4200
 
 
4201
 
 
4202
int zend_isset_isempty_prop_obj_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4203
{
 
4204
        return zend_isset_isempty_dim_prop_obj_handler(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 
4205
}
 
4206
 
 
4207
 
 
4208
int zend_exit_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4209
{
 
4210
        if (opline->op1.op_type != IS_UNUSED) {
 
4211
                zval *ptr;
 
4212
 
 
4213
                ptr = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
4214
                if (Z_TYPE_P(ptr) == IS_LONG) {
 
4215
                        EG(exit_status) = Z_LVAL_P(ptr);
 
4216
                } else {
 
4217
                        zend_print_variable(ptr);
 
4218
                }
 
4219
                FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
4220
        }
 
4221
        zend_bailout();
 
4222
        NEXT_OPCODE();
 
4223
}
 
4224
 
 
4225
 
 
4226
int zend_begin_silence_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4227
{
 
4228
        EX_T(opline->result.u.var).tmp_var.value.lval = EG(error_reporting);
 
4229
        EX_T(opline->result.u.var).tmp_var.type = IS_LONG;  /* shouldn't be necessary */
 
4230
        zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
 
4231
        NEXT_OPCODE();
 
4232
}
 
4233
 
 
4234
 
 
4235
int zend_raise_abstract_error_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4236
{
 
4237
        zend_error(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name, op_array->function_name);
 
4238
        NEXT_OPCODE(); /* Never reached */
 
4239
}
 
4240
 
 
4241
 
 
4242
int zend_end_silence_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4243
{
 
4244
        zval restored_error_reporting;
 
4245
        
 
4246
        if (!EG(error_reporting)) {
 
4247
                restored_error_reporting.type = IS_LONG;
 
4248
                restored_error_reporting.value.lval = EX_T(opline->op1.u.var).tmp_var.value.lval;
 
4249
                convert_to_string(&restored_error_reporting);
 
4250
                zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
 
4251
                zendi_zval_dtor(restored_error_reporting);
 
4252
        }
 
4253
        NEXT_OPCODE();
 
4254
}
 
4255
 
 
4256
 
 
4257
int zend_qm_assign_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4258
{
 
4259
        zval *value = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
4260
 
 
4261
        EX_T(opline->result.u.var).tmp_var = *value;
 
4262
        if (!EG(free_op1)) {
 
4263
                zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
 
4264
        }
 
4265
        NEXT_OPCODE();
 
4266
}
 
4267
 
 
4268
 
 
4269
int zend_ext_stmt_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4270
{
 
4271
        if (!EG(no_extensions)) {
 
4272
                zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, op_array TSRMLS_CC);
 
4273
        }
 
4274
        NEXT_OPCODE();
 
4275
}
 
4276
 
 
4277
 
 
4278
int zend_ext_fcall_begin_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4279
{
 
4280
        if (!EG(no_extensions)) {
 
4281
                zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, op_array TSRMLS_CC);
 
4282
        }
 
4283
        NEXT_OPCODE();
 
4284
}
 
4285
 
 
4286
 
 
4287
int zend_ext_fcall_end_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4288
{
 
4289
        if (!EG(no_extensions)) {
 
4290
                zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, op_array TSRMLS_CC);
 
4291
        }
 
4292
        NEXT_OPCODE();
 
4293
}
 
4294
 
 
4295
 
 
4296
int zend_declare_class_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4297
{
 
4298
        EX_T(opline->result.u.var).class_entry = do_bind_class(opline, EG(class_table), 0 TSRMLS_CC);
 
4299
        NEXT_OPCODE();
 
4300
}
 
4301
 
 
4302
 
 
4303
int zend_declare_inherited_class_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4304
{
 
4305
        EX_T(opline->result.u.var).class_entry = do_bind_inherited_class(opline, EG(class_table), EX_T(opline->extended_value).class_entry, 0 TSRMLS_CC);
 
4306
        NEXT_OPCODE();
 
4307
}
 
4308
 
 
4309
 
 
4310
int zend_declare_function_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4311
{
 
4312
        do_bind_function(opline, EG(function_table), 0);
 
4313
        NEXT_OPCODE();
 
4314
}
 
4315
 
 
4316
 
 
4317
int zend_ticks_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4318
{
 
4319
        if (++EG(ticks_count)>=opline->op1.u.constant.value.lval) {
 
4320
                EG(ticks_count)=0;
 
4321
                if (zend_ticks_function) {
 
4322
                        zend_ticks_function(opline->op1.u.constant.value.lval);
 
4323
                }
 
4324
        }
 
4325
        NEXT_OPCODE();
 
4326
}
 
4327
 
 
4328
 
 
4329
int zend_instanceof_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4330
{
 
4331
        zval *expr = get_zval_ptr(&opline->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
 
4332
        zend_bool result;
 
4333
 
 
4334
        if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
 
4335
                result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.u.var).class_entry TSRMLS_CC);
 
4336
        } else {
 
4337
                result = 0;
 
4338
        }
 
4339
        ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, result);
 
4340
        FREE_OP(EX(Ts), &opline->op1, EG(free_op1));
 
4341
        NEXT_OPCODE();
 
4342
}
 
4343
 
 
4344
 
 
4345
int zend_ext_nop_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4346
{
 
4347
        NEXT_OPCODE();
 
4348
}
 
4349
 
 
4350
 
 
4351
int zend_nop_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4352
{
 
4353
        NEXT_OPCODE();
 
4354
}
 
4355
 
 
4356
int zend_add_interface_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4357
{
 
4358
        zend_class_entry *ce = EX_T(opline->op1.u.var).class_entry;
 
4359
        zend_class_entry *iface = EX_T(opline->op2.u.var).class_entry;
 
4360
 
 
4361
        if (!(iface->ce_flags & ZEND_ACC_INTERFACE)) {
 
4362
                zend_error(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name);
 
4363
        }
 
4364
 
 
4365
        ce->interfaces[opline->extended_value] = iface;
 
4366
 
 
4367
        zend_do_implement_interface(ce, iface TSRMLS_CC);
 
4368
 
 
4369
        NEXT_OPCODE();
 
4370
}
 
4371
 
 
4372
 
 
4373
int zend_handle_exception_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4374
{
 
4375
        zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
 
4376
        int i;
 
4377
        int encapsulating_block=-1;
 
4378
        zval **stack_zval_pp;
 
4379
        
 
4380
        stack_zval_pp = (zval **) EG(argument_stack).top_element - 1;
 
4381
        while (*stack_zval_pp != NULL) {
 
4382
                zval_ptr_dtor(stack_zval_pp);
 
4383
                EG(argument_stack).top_element--;
 
4384
                EG(argument_stack).top--;
 
4385
                stack_zval_pp--;
 
4386
        }
 
4387
 
 
4388
        for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
 
4389
                if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
 
4390
                        /* further blocks will not be relevant... */
 
4391
                        break;
 
4392
                }
 
4393
                if (op_num >= EG(active_op_array)->try_catch_array[i].try_op
 
4394
                        && op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
 
4395
                        encapsulating_block = i;
 
4396
                }
 
4397
        }
 
4398
 
 
4399
        while (EX(fbc)) {
 
4400
                if (EX(object)) {
 
4401
                        zval_ptr_dtor(&EX(object));
 
4402
                }
 
4403
                zend_ptr_stack_n_pop(&EG(arg_types_stack), 3, &EX(calling_scope), &EX(object), &EX(fbc));
 
4404
        }
 
4405
 
 
4406
        if (encapsulating_block == -1) {
 
4407
                RETURN_FROM_EXECUTE_LOOP(execute_data);
 
4408
        } else {
 
4409
                SET_OPCODE(&op_array->opcodes[EG(active_op_array)->try_catch_array[encapsulating_block].catch_op]);
 
4410
                return 0;
 
4411
        }
 
4412
}
 
4413
 
 
4414
 
 
4415
int zend_verify_abstract_class_handler(ZEND_OPCODE_HANDLER_ARGS)
 
4416
{
 
4417
        zend_verify_abstract_class(EX_T(opline->op1.u.var).class_entry TSRMLS_CC);
 
4418
        NEXT_OPCODE();
 
4419
}
 
4420
 
 
4421
 
 
4422
void zend_init_opcodes_handlers()
 
4423
{
 
4424
        memset(zend_opcode_handlers, 0, sizeof(zend_opcode_handlers));
 
4425
        zend_opcode_handlers[ZEND_NOP] = zend_nop_handler;
 
4426
        zend_opcode_handlers[ZEND_ADD] = zend_add_handler;
 
4427
        zend_opcode_handlers[ZEND_SUB] = zend_sub_handler;
 
4428
        zend_opcode_handlers[ZEND_MUL] = zend_mul_handler;
 
4429
        zend_opcode_handlers[ZEND_DIV] = zend_div_handler;
 
4430
        zend_opcode_handlers[ZEND_MOD] = zend_mod_handler;
 
4431
        zend_opcode_handlers[ZEND_SL] = zend_sl_handler;
 
4432
        zend_opcode_handlers[ZEND_SR] = zend_sr_handler;
 
4433
        zend_opcode_handlers[ZEND_CONCAT] = zend_concat_handler;
 
4434
        zend_opcode_handlers[ZEND_BW_OR] = zend_bw_or_handler;
 
4435
        zend_opcode_handlers[ZEND_BW_AND] = zend_bw_and_handler;
 
4436
        zend_opcode_handlers[ZEND_BW_XOR] = zend_bw_xor_handler;
 
4437
        zend_opcode_handlers[ZEND_BW_NOT] = zend_bw_not_handler;
 
4438
        zend_opcode_handlers[ZEND_BOOL_NOT] = zend_bool_not_handler;
 
4439
        zend_opcode_handlers[ZEND_BOOL_XOR] = zend_bool_xor_handler;
 
4440
        zend_opcode_handlers[ZEND_IS_IDENTICAL] = zend_is_identical_handler;
 
4441
        zend_opcode_handlers[ZEND_IS_NOT_IDENTICAL] = zend_is_not_identical_handler;
 
4442
        zend_opcode_handlers[ZEND_IS_EQUAL] = zend_is_equal_handler;
 
4443
        zend_opcode_handlers[ZEND_IS_NOT_EQUAL] = zend_is_not_equal_handler;
 
4444
        zend_opcode_handlers[ZEND_IS_SMALLER] = zend_is_smaller_handler;
 
4445
        zend_opcode_handlers[ZEND_IS_SMALLER_OR_EQUAL] = zend_is_smaller_or_equal_handler;
 
4446
        zend_opcode_handlers[ZEND_CAST] = zend_cast_handler;
 
4447
        zend_opcode_handlers[ZEND_QM_ASSIGN] = zend_qm_assign_handler;
 
4448
 
 
4449
        zend_opcode_handlers[ZEND_ASSIGN_ADD] = zend_assign_add_handler;
 
4450
        zend_opcode_handlers[ZEND_ASSIGN_SUB] = zend_assign_sub_handler;
 
4451
        zend_opcode_handlers[ZEND_ASSIGN_MUL] = zend_assign_mul_handler;
 
4452
        zend_opcode_handlers[ZEND_ASSIGN_DIV] = zend_assign_div_handler;
 
4453
        zend_opcode_handlers[ZEND_ASSIGN_MOD] = zend_assign_mod_handler;
 
4454
        zend_opcode_handlers[ZEND_ASSIGN_SL] = zend_assign_sl_handler;
 
4455
        zend_opcode_handlers[ZEND_ASSIGN_SR] = zend_assign_sr_handler;
 
4456
        zend_opcode_handlers[ZEND_ASSIGN_CONCAT] = zend_assign_concat_handler;
 
4457
        zend_opcode_handlers[ZEND_ASSIGN_BW_OR] = zend_assign_bw_or_handler;
 
4458
        zend_opcode_handlers[ZEND_ASSIGN_BW_AND] = zend_assign_bw_and_handler;
 
4459
        zend_opcode_handlers[ZEND_ASSIGN_BW_XOR] = zend_assign_bw_xor_handler;
 
4460
 
 
4461
        zend_opcode_handlers[ZEND_PRE_INC] = zend_pre_inc_handler;
 
4462
        zend_opcode_handlers[ZEND_PRE_DEC] = zend_pre_dec_handler;
 
4463
        zend_opcode_handlers[ZEND_POST_INC] = zend_post_inc_handler;
 
4464
        zend_opcode_handlers[ZEND_POST_DEC] = zend_post_dec_handler;
 
4465
 
 
4466
        zend_opcode_handlers[ZEND_ASSIGN] = zend_assign_handler;
 
4467
        zend_opcode_handlers[ZEND_ASSIGN_REF] = zend_assign_ref_handler;
 
4468
 
 
4469
        zend_opcode_handlers[ZEND_ECHO] = zend_echo_handler;
 
4470
        zend_opcode_handlers[ZEND_PRINT] = zend_print_handler;
 
4471
 
 
4472
        zend_opcode_handlers[ZEND_JMP] = zend_jmp_handler;
 
4473
        zend_opcode_handlers[ZEND_JMPZ] = zend_jmpz_handler;
 
4474
        zend_opcode_handlers[ZEND_JMPNZ] = zend_jmpnz_handler;
 
4475
        zend_opcode_handlers[ZEND_JMPZNZ] = zend_jmpznz_handler;
 
4476
        zend_opcode_handlers[ZEND_JMPZ_EX] = zend_jmpz_ex_handler;
 
4477
        zend_opcode_handlers[ZEND_JMPNZ_EX] = zend_jmpnz_ex_handler;
 
4478
        zend_opcode_handlers[ZEND_CASE] = zend_case_handler;
 
4479
        zend_opcode_handlers[ZEND_SWITCH_FREE] = zend_switch_free_handler;
 
4480
        zend_opcode_handlers[ZEND_BRK] = zend_brk_handler;
 
4481
        zend_opcode_handlers[ZEND_CONT] = zend_cont_handler;
 
4482
        zend_opcode_handlers[ZEND_BOOL] = zend_bool_handler;
 
4483
 
 
4484
        zend_opcode_handlers[ZEND_INIT_STRING] = zend_init_string_handler;
 
4485
        zend_opcode_handlers[ZEND_ADD_CHAR] = zend_add_char_handler;
 
4486
        zend_opcode_handlers[ZEND_ADD_STRING] = zend_add_string_handler;
 
4487
        zend_opcode_handlers[ZEND_ADD_VAR] = zend_add_var_handler;
 
4488
 
 
4489
        zend_opcode_handlers[ZEND_BEGIN_SILENCE] = zend_begin_silence_handler;
 
4490
        zend_opcode_handlers[ZEND_END_SILENCE] = zend_end_silence_handler;
 
4491
 
 
4492
        zend_opcode_handlers[ZEND_INIT_FCALL_BY_NAME] = zend_init_fcall_by_name_handler;
 
4493
        zend_opcode_handlers[ZEND_DO_FCALL] = zend_do_fcall_handler;
 
4494
        zend_opcode_handlers[ZEND_DO_FCALL_BY_NAME] = zend_do_fcall_by_name_handler;
 
4495
        zend_opcode_handlers[ZEND_RETURN] = zend_return_handler;
 
4496
 
 
4497
        zend_opcode_handlers[ZEND_RECV] = zend_recv_handler;
 
4498
        zend_opcode_handlers[ZEND_RECV_INIT] = zend_recv_init_handler;
 
4499
 
 
4500
        zend_opcode_handlers[ZEND_SEND_VAL] = zend_send_val_handler;
 
4501
        zend_opcode_handlers[ZEND_SEND_VAR] = zend_send_var_handler;
 
4502
        zend_opcode_handlers[ZEND_SEND_REF] = zend_send_ref_handler;
 
4503
 
 
4504
        zend_opcode_handlers[ZEND_NEW] = zend_new_handler;
 
4505
        zend_opcode_handlers[ZEND_JMP_NO_CTOR] = zend_jmp_no_ctor_handler;
 
4506
        zend_opcode_handlers[ZEND_FREE] = zend_free_handler;
 
4507
 
 
4508
        zend_opcode_handlers[ZEND_INIT_ARRAY] = zend_init_array_handler;
 
4509
        zend_opcode_handlers[ZEND_ADD_ARRAY_ELEMENT] = zend_add_array_element_handler;
 
4510
 
 
4511
        zend_opcode_handlers[ZEND_INCLUDE_OR_EVAL] = zend_include_or_eval_handler;
 
4512
 
 
4513
        zend_opcode_handlers[ZEND_UNSET_VAR] = zend_unset_var_handler;
 
4514
        zend_opcode_handlers[ZEND_UNSET_DIM_OBJ] = zend_unset_dim_obj_handler;
 
4515
 
 
4516
        zend_opcode_handlers[ZEND_FE_RESET] = zend_fe_reset_handler;
 
4517
        zend_opcode_handlers[ZEND_FE_FETCH] = zend_fe_fetch_handler;
 
4518
 
 
4519
        zend_opcode_handlers[ZEND_EXIT] = zend_exit_handler;
 
4520
 
 
4521
        zend_opcode_handlers[ZEND_FETCH_R] = zend_fetch_r_handler;
 
4522
        zend_opcode_handlers[ZEND_FETCH_DIM_R] = zend_fetch_dim_r_handler;
 
4523
        zend_opcode_handlers[ZEND_FETCH_OBJ_R] = zend_fetch_obj_r_handler;
 
4524
        zend_opcode_handlers[ZEND_FETCH_W] = zend_fetch_w_handler;
 
4525
        zend_opcode_handlers[ZEND_FETCH_DIM_W] = zend_fetch_dim_w_handler;
 
4526
        zend_opcode_handlers[ZEND_FETCH_OBJ_W] = zend_fetch_obj_w_handler;
 
4527
        zend_opcode_handlers[ZEND_FETCH_RW] = zend_fetch_rw_handler;
 
4528
        zend_opcode_handlers[ZEND_FETCH_DIM_RW] = zend_fetch_dim_rw_handler;
 
4529
        zend_opcode_handlers[ZEND_FETCH_OBJ_RW] = zend_fetch_obj_rw_handler;
 
4530
        zend_opcode_handlers[ZEND_FETCH_IS] = zend_fetch_is_handler;
 
4531
        zend_opcode_handlers[ZEND_FETCH_DIM_IS] = zend_fetch_dim_is_handler;
 
4532
        zend_opcode_handlers[ZEND_FETCH_OBJ_IS] = zend_fetch_obj_is_handler;
 
4533
        zend_opcode_handlers[ZEND_FETCH_FUNC_ARG] = zend_fetch_func_arg_handler;
 
4534
        zend_opcode_handlers[ZEND_FETCH_DIM_FUNC_ARG] = zend_fetch_dim_func_arg_handler;
 
4535
        zend_opcode_handlers[ZEND_FETCH_OBJ_FUNC_ARG] = zend_fetch_obj_func_arg_handler;
 
4536
        zend_opcode_handlers[ZEND_FETCH_UNSET] = zend_fetch_unset_handler;
 
4537
        zend_opcode_handlers[ZEND_FETCH_DIM_UNSET] = zend_fetch_dim_unset_handler;
 
4538
        zend_opcode_handlers[ZEND_FETCH_OBJ_UNSET] = zend_fetch_obj_unset_handler;
 
4539
 
 
4540
        zend_opcode_handlers[ZEND_FETCH_DIM_TMP_VAR] = zend_fetch_dim_tmp_var_handler;
 
4541
        zend_opcode_handlers[ZEND_FETCH_CONSTANT] = zend_fetch_constant_handler;
 
4542
 
 
4543
        zend_opcode_handlers[ZEND_EXT_STMT] = zend_ext_stmt_handler;
 
4544
        zend_opcode_handlers[ZEND_EXT_FCALL_BEGIN] = zend_ext_fcall_begin_handler;
 
4545
        zend_opcode_handlers[ZEND_EXT_FCALL_END] = zend_ext_fcall_end_handler;
 
4546
        zend_opcode_handlers[ZEND_EXT_NOP] = zend_ext_nop_handler;
 
4547
 
 
4548
        zend_opcode_handlers[ZEND_TICKS] = zend_ticks_handler;
 
4549
 
 
4550
        zend_opcode_handlers[ZEND_SEND_VAR_NO_REF] = zend_send_var_no_ref_handler;
 
4551
 
 
4552
        zend_opcode_handlers[ZEND_CATCH] = zend_catch_handler;
 
4553
        zend_opcode_handlers[ZEND_THROW] = zend_throw_handler;
 
4554
 
 
4555
        zend_opcode_handlers[ZEND_FETCH_CLASS] = zend_fetch_class_handler;
 
4556
 
 
4557
        zend_opcode_handlers[ZEND_CLONE] = zend_clone_handler;
 
4558
 
 
4559
        zend_opcode_handlers[ZEND_INIT_CTOR_CALL] = zend_init_ctor_call_handler;
 
4560
        zend_opcode_handlers[ZEND_INIT_METHOD_CALL] = zend_init_method_call_handler;
 
4561
        zend_opcode_handlers[ZEND_INIT_STATIC_METHOD_CALL] = zend_init_static_method_call_handler;
 
4562
 
 
4563
        zend_opcode_handlers[ZEND_ISSET_ISEMPTY_VAR] = zend_isset_isempty_var_handler;
 
4564
        zend_opcode_handlers[ZEND_ISSET_ISEMPTY_DIM_OBJ] = zend_isset_isempty_dim_obj_handler;
 
4565
        zend_opcode_handlers[ZEND_ISSET_ISEMPTY_PROP_OBJ] = zend_isset_isempty_prop_obj_handler;
 
4566
 
 
4567
        zend_opcode_handlers[ZEND_PRE_INC_OBJ] = zend_pre_inc_obj_handler;
 
4568
        zend_opcode_handlers[ZEND_PRE_DEC_OBJ] = zend_pre_dec_obj_handler;
 
4569
        zend_opcode_handlers[ZEND_POST_INC_OBJ] = zend_post_inc_obj_handler;
 
4570
        zend_opcode_handlers[ZEND_POST_DEC_OBJ] = zend_post_dec_obj_handler;
 
4571
 
 
4572
        zend_opcode_handlers[ZEND_ASSIGN_OBJ] = zend_assign_obj_handler;
 
4573
        zend_opcode_handlers[ZEND_OP_DATA] = NULL;
 
4574
 
 
4575
        zend_opcode_handlers[ZEND_INSTANCEOF] = zend_instanceof_handler;
 
4576
 
 
4577
        zend_opcode_handlers[ZEND_DECLARE_CLASS] = zend_declare_class_handler;
 
4578
        zend_opcode_handlers[ZEND_DECLARE_INHERITED_CLASS] = zend_declare_inherited_class_handler;
 
4579
        zend_opcode_handlers[ZEND_DECLARE_FUNCTION] = zend_declare_function_handler;
 
4580
 
 
4581
        zend_opcode_handlers[ZEND_RAISE_ABSTRACT_ERROR] = zend_raise_abstract_error_handler;
 
4582
 
 
4583
        zend_opcode_handlers[ZEND_ADD_INTERFACE] = zend_add_interface_handler;
 
4584
        zend_opcode_handlers[ZEND_VERIFY_ABSTRACT_CLASS] = zend_verify_abstract_class_handler;
 
4585
 
 
4586
        zend_opcode_handlers[ZEND_ASSIGN_DIM] = zend_assign_dim_handler;
 
4587
 
 
4588
        zend_opcode_handlers[ZEND_HANDLE_EXCEPTION] = zend_handle_exception_handler;
 
4589
}
 
4590
 
 
4591
/*
 
4592
 * Local variables:
 
4593
 * tab-width: 4
 
4594
 * c-basic-offset: 4
 
4595
 * indent-tabs-mode: t
 
4596
 * End:
 
4597
 */