zend_vm_def.h revision 80497ea7dfade2ccd032ef65103c0a113338653a
1/* 2 +----------------------------------------------------------------------+ 3 | Zend Engine | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1998-2012 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 | Dmitry Stogov <dmitry@zend.com> | 18 +----------------------------------------------------------------------+ 19*/ 20 21/* $Id$ */ 22 23/* If you change this file, please regenerate the zend_vm_execute.h and 24 * zend_vm_opcodes.h files by running: 25 * php zend_vm_gen.php 26 */ 27 28ZEND_VM_HANDLER(1, ZEND_ADD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 29{ 30 USE_OPLINE 31 zend_free_op free_op1, free_op2; 32 33 SAVE_OPLINE(); 34 fast_add_function(&EX_T(opline->result.var).tmp_var, 35 GET_OP1_ZVAL_PTR(BP_VAR_R), 36 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 37 FREE_OP1(); 38 FREE_OP2(); 39 CHECK_EXCEPTION(); 40 ZEND_VM_NEXT_OPCODE(); 41} 42 43ZEND_VM_HANDLER(2, ZEND_SUB, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 44{ 45 USE_OPLINE 46 zend_free_op free_op1, free_op2; 47 48 SAVE_OPLINE(); 49 fast_sub_function(&EX_T(opline->result.var).tmp_var, 50 GET_OP1_ZVAL_PTR(BP_VAR_R), 51 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 52 FREE_OP1(); 53 FREE_OP2(); 54 CHECK_EXCEPTION(); 55 ZEND_VM_NEXT_OPCODE(); 56} 57 58ZEND_VM_HANDLER(3, ZEND_MUL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 59{ 60 USE_OPLINE 61 zend_free_op free_op1, free_op2; 62 63 SAVE_OPLINE(); 64 fast_mul_function(&EX_T(opline->result.var).tmp_var, 65 GET_OP1_ZVAL_PTR(BP_VAR_R), 66 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 67 FREE_OP1(); 68 FREE_OP2(); 69 CHECK_EXCEPTION(); 70 ZEND_VM_NEXT_OPCODE(); 71} 72 73ZEND_VM_HANDLER(4, ZEND_DIV, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 74{ 75 USE_OPLINE 76 zend_free_op free_op1, free_op2; 77 78 SAVE_OPLINE(); 79 fast_div_function(&EX_T(opline->result.var).tmp_var, 80 GET_OP1_ZVAL_PTR(BP_VAR_R), 81 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 82 FREE_OP1(); 83 FREE_OP2(); 84 CHECK_EXCEPTION(); 85 ZEND_VM_NEXT_OPCODE(); 86} 87 88ZEND_VM_HANDLER(5, ZEND_MOD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 89{ 90 USE_OPLINE 91 zend_free_op free_op1, free_op2; 92 93 SAVE_OPLINE(); 94 fast_mod_function(&EX_T(opline->result.var).tmp_var, 95 GET_OP1_ZVAL_PTR(BP_VAR_R), 96 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 97 FREE_OP1(); 98 FREE_OP2(); 99 CHECK_EXCEPTION(); 100 ZEND_VM_NEXT_OPCODE(); 101} 102 103ZEND_VM_HANDLER(6, ZEND_SL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 104{ 105 USE_OPLINE 106 zend_free_op free_op1, free_op2; 107 108 SAVE_OPLINE(); 109 shift_left_function(&EX_T(opline->result.var).tmp_var, 110 GET_OP1_ZVAL_PTR(BP_VAR_R), 111 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 112 FREE_OP1(); 113 FREE_OP2(); 114 CHECK_EXCEPTION(); 115 ZEND_VM_NEXT_OPCODE(); 116} 117 118ZEND_VM_HANDLER(7, ZEND_SR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 119{ 120 USE_OPLINE 121 zend_free_op free_op1, free_op2; 122 123 SAVE_OPLINE(); 124 shift_right_function(&EX_T(opline->result.var).tmp_var, 125 GET_OP1_ZVAL_PTR(BP_VAR_R), 126 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 127 FREE_OP1(); 128 FREE_OP2(); 129 CHECK_EXCEPTION(); 130 ZEND_VM_NEXT_OPCODE(); 131} 132 133ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 134{ 135 USE_OPLINE 136 zend_free_op free_op1, free_op2; 137 138 SAVE_OPLINE(); 139 concat_function(&EX_T(opline->result.var).tmp_var, 140 GET_OP1_ZVAL_PTR(BP_VAR_R), 141 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 142 FREE_OP1(); 143 FREE_OP2(); 144 CHECK_EXCEPTION(); 145 ZEND_VM_NEXT_OPCODE(); 146} 147 148ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 149{ 150 USE_OPLINE 151 zend_free_op free_op1, free_op2; 152 153 SAVE_OPLINE(); 154 is_identical_function(&EX_T(opline->result.var).tmp_var, 155 GET_OP1_ZVAL_PTR(BP_VAR_R), 156 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 157 FREE_OP1(); 158 FREE_OP2(); 159 CHECK_EXCEPTION(); 160 ZEND_VM_NEXT_OPCODE(); 161} 162 163ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 164{ 165 USE_OPLINE 166 zend_free_op free_op1, free_op2; 167 zval *result = &EX_T(opline->result.var).tmp_var; 168 169 SAVE_OPLINE(); 170 is_identical_function(result, 171 GET_OP1_ZVAL_PTR(BP_VAR_R), 172 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 173 Z_LVAL_P(result) = !Z_LVAL_P(result); 174 FREE_OP1(); 175 FREE_OP2(); 176 CHECK_EXCEPTION(); 177 ZEND_VM_NEXT_OPCODE(); 178} 179 180ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 181{ 182 USE_OPLINE 183 zend_free_op free_op1, free_op2; 184 zval *result = &EX_T(opline->result.var).tmp_var; 185 186 SAVE_OPLINE(); 187 ZVAL_BOOL(result, fast_equal_function(result, 188 GET_OP1_ZVAL_PTR(BP_VAR_R), 189 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC)); 190 FREE_OP1(); 191 FREE_OP2(); 192 CHECK_EXCEPTION(); 193 ZEND_VM_NEXT_OPCODE(); 194} 195 196ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 197{ 198 USE_OPLINE 199 zend_free_op free_op1, free_op2; 200 zval *result = &EX_T(opline->result.var).tmp_var; 201 202 SAVE_OPLINE(); 203 ZVAL_BOOL(result, fast_not_equal_function(result, 204 GET_OP1_ZVAL_PTR(BP_VAR_R), 205 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC)); 206 FREE_OP1(); 207 FREE_OP2(); 208 CHECK_EXCEPTION(); 209 ZEND_VM_NEXT_OPCODE(); 210} 211 212ZEND_VM_HANDLER(19, ZEND_IS_SMALLER, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 213{ 214 USE_OPLINE 215 zend_free_op free_op1, free_op2; 216 zval *result = &EX_T(opline->result.var).tmp_var; 217 218 SAVE_OPLINE(); 219 ZVAL_BOOL(result, fast_is_smaller_function(result, 220 GET_OP1_ZVAL_PTR(BP_VAR_R), 221 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC)); 222 FREE_OP1(); 223 FREE_OP2(); 224 CHECK_EXCEPTION(); 225 ZEND_VM_NEXT_OPCODE(); 226} 227 228ZEND_VM_HANDLER(20, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 229{ 230 USE_OPLINE 231 zend_free_op free_op1, free_op2; 232 zval *result = &EX_T(opline->result.var).tmp_var; 233 234 SAVE_OPLINE(); 235 ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result, 236 GET_OP1_ZVAL_PTR(BP_VAR_R), 237 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC)); 238 FREE_OP1(); 239 FREE_OP2(); 240 CHECK_EXCEPTION(); 241 ZEND_VM_NEXT_OPCODE(); 242} 243 244ZEND_VM_HANDLER(9, ZEND_BW_OR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 245{ 246 USE_OPLINE 247 zend_free_op free_op1, free_op2; 248 249 SAVE_OPLINE(); 250 bitwise_or_function(&EX_T(opline->result.var).tmp_var, 251 GET_OP1_ZVAL_PTR(BP_VAR_R), 252 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 253 FREE_OP1(); 254 FREE_OP2(); 255 CHECK_EXCEPTION(); 256 ZEND_VM_NEXT_OPCODE(); 257} 258 259ZEND_VM_HANDLER(10, ZEND_BW_AND, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 260{ 261 USE_OPLINE 262 zend_free_op free_op1, free_op2; 263 264 SAVE_OPLINE(); 265 bitwise_and_function(&EX_T(opline->result.var).tmp_var, 266 GET_OP1_ZVAL_PTR(BP_VAR_R), 267 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 268 FREE_OP1(); 269 FREE_OP2(); 270 CHECK_EXCEPTION(); 271 ZEND_VM_NEXT_OPCODE(); 272} 273 274ZEND_VM_HANDLER(11, ZEND_BW_XOR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 275{ 276 USE_OPLINE 277 zend_free_op free_op1, free_op2; 278 279 SAVE_OPLINE(); 280 bitwise_xor_function(&EX_T(opline->result.var).tmp_var, 281 GET_OP1_ZVAL_PTR(BP_VAR_R), 282 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 283 FREE_OP1(); 284 FREE_OP2(); 285 CHECK_EXCEPTION(); 286 ZEND_VM_NEXT_OPCODE(); 287} 288 289ZEND_VM_HANDLER(14, ZEND_BOOL_XOR, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 290{ 291 USE_OPLINE 292 zend_free_op free_op1, free_op2; 293 294 SAVE_OPLINE(); 295 boolean_xor_function(&EX_T(opline->result.var).tmp_var, 296 GET_OP1_ZVAL_PTR(BP_VAR_R), 297 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 298 FREE_OP1(); 299 FREE_OP2(); 300 CHECK_EXCEPTION(); 301 ZEND_VM_NEXT_OPCODE(); 302} 303 304ZEND_VM_HANDLER(12, ZEND_BW_NOT, CONST|TMP|VAR|CV, ANY) 305{ 306 USE_OPLINE 307 zend_free_op free_op1; 308 309 SAVE_OPLINE(); 310 bitwise_not_function(&EX_T(opline->result.var).tmp_var, 311 GET_OP1_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 312 FREE_OP1(); 313 CHECK_EXCEPTION(); 314 ZEND_VM_NEXT_OPCODE(); 315} 316 317ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMP|VAR|CV, ANY) 318{ 319 USE_OPLINE 320 zend_free_op free_op1; 321 322 SAVE_OPLINE(); 323 boolean_not_function(&EX_T(opline->result.var).tmp_var, 324 GET_OP1_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 325 FREE_OP1(); 326 CHECK_EXCEPTION(); 327 ZEND_VM_NEXT_OPCODE(); 328} 329 330ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC)) 331{ 332 USE_OPLINE 333 zend_free_op free_op1, free_op2, free_op_data1; 334 zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); 335 zval *object; 336 zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R); 337 zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R); 338 int have_get_ptr = 0; 339 340 if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) { 341 zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); 342 } 343 344 make_real_object(object_ptr TSRMLS_CC); 345 object = *object_ptr; 346 347 if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { 348 zend_error(E_WARNING, "Attempt to assign property of non-object"); 349 FREE_OP2(); 350 FREE_OP(free_op_data1); 351 352 if (RETURN_VALUE_USED(opline)) { 353 PZVAL_LOCK(&EG(uninitialized_zval)); 354 EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); 355 EX_T(opline->result.var).var.ptr_ptr = NULL; 356 } 357 } else { 358 /* here we are sure we are dealing with an object */ 359 if (IS_OP2_TMP_FREE()) { 360 MAKE_REAL_ZVAL_PTR(property); 361 } 362 363 /* here property is a string */ 364 if (opline->extended_value == ZEND_ASSIGN_OBJ 365 && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { 366 zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 367 if (zptr != NULL) { /* NULL means no success in getting PTR */ 368 SEPARATE_ZVAL_IF_NOT_REF(zptr); 369 370 have_get_ptr = 1; 371 binary_op(*zptr, *zptr, value TSRMLS_CC); 372 if (RETURN_VALUE_USED(opline)) { 373 PZVAL_LOCK(*zptr); 374 EX_T(opline->result.var).var.ptr = *zptr; 375 EX_T(opline->result.var).var.ptr_ptr = NULL; 376 } 377 } 378 } 379 380 if (!have_get_ptr) { 381 zval *z = NULL; 382 383 if (opline->extended_value == ZEND_ASSIGN_OBJ) { 384 if (Z_OBJ_HT_P(object)->read_property) { 385 z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 386 } 387 } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { 388 if (Z_OBJ_HT_P(object)->read_dimension) { 389 z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC); 390 } 391 } 392 if (z) { 393 if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { 394 zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); 395 396 if (Z_REFCOUNT_P(z) == 0) { 397 GC_REMOVE_ZVAL_FROM_BUFFER(z); 398 zval_dtor(z); 399 FREE_ZVAL(z); 400 } 401 z = value; 402 } 403 Z_ADDREF_P(z); 404 SEPARATE_ZVAL_IF_NOT_REF(&z); 405 binary_op(z, z, value TSRMLS_CC); 406 if (opline->extended_value == ZEND_ASSIGN_OBJ) { 407 Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 408 } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ { 409 Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC); 410 } 411 if (RETURN_VALUE_USED(opline)) { 412 PZVAL_LOCK(z); 413 EX_T(opline->result.var).var.ptr = z; 414 EX_T(opline->result.var).var.ptr_ptr = NULL; 415 } 416 zval_ptr_dtor(&z); 417 } else { 418 zend_error(E_WARNING, "Attempt to assign property of non-object"); 419 if (RETURN_VALUE_USED(opline)) { 420 PZVAL_LOCK(&EG(uninitialized_zval)); 421 EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); 422 EX_T(opline->result.var).var.ptr_ptr = NULL; 423 } 424 } 425 } 426 427 if (IS_OP2_TMP_FREE()) { 428 zval_ptr_dtor(&property); 429 } else { 430 FREE_OP2(); 431 } 432 FREE_OP(free_op_data1); 433 } 434 435 FREE_OP1_VAR_PTR(); 436 /* assign_obj has two opcodes! */ 437 CHECK_EXCEPTION(); 438 ZEND_VM_INC_OPCODE(); 439 ZEND_VM_NEXT_OPCODE(); 440} 441 442ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC)) 443{ 444 USE_OPLINE 445 zend_free_op free_op1, free_op2, free_op_data2, free_op_data1; 446 zval **var_ptr; 447 zval *value; 448 449 SAVE_OPLINE(); 450 switch (opline->extended_value) { 451 case ZEND_ASSIGN_OBJ: 452 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op); 453 break; 454 case ZEND_ASSIGN_DIM: { 455 zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); 456 457 if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { 458 zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); 459 } else if (UNEXPECTED(Z_TYPE_PP(container) == IS_OBJECT)) { 460 if (OP1_TYPE == IS_VAR && !OP1_FREE) { 461 Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */ 462 } 463 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op); 464 } else { 465 zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R); 466 467 zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, OP2_TYPE, BP_VAR_RW TSRMLS_CC); 468 value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R); 469 var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC); 470 } 471 } 472 break; 473 default: 474 value = GET_OP2_ZVAL_PTR(BP_VAR_R); 475 var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); 476 /* do nothing */ 477 break; 478 } 479 480 if (UNEXPECTED(var_ptr == NULL)) { 481 zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); 482 } 483 484 if (UNEXPECTED(*var_ptr == &EG(error_zval))) { 485 if (RETURN_VALUE_USED(opline)) { 486 PZVAL_LOCK(&EG(uninitialized_zval)); 487 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 488 } 489 FREE_OP2(); 490 FREE_OP1_VAR_PTR(); 491 CHECK_EXCEPTION(); 492 if (opline->extended_value == ZEND_ASSIGN_DIM) { 493 ZEND_VM_INC_OPCODE(); 494 } 495 ZEND_VM_NEXT_OPCODE(); 496 } 497 498 SEPARATE_ZVAL_IF_NOT_REF(var_ptr); 499 500 if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT) 501 && Z_OBJ_HANDLER_PP(var_ptr, get) 502 && Z_OBJ_HANDLER_PP(var_ptr, set)) { 503 /* proxy object */ 504 zval *objval = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC); 505 Z_ADDREF_P(objval); 506 binary_op(objval, objval, value TSRMLS_CC); 507 Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, objval TSRMLS_CC); 508 zval_ptr_dtor(&objval); 509 } else { 510 binary_op(*var_ptr, *var_ptr, value TSRMLS_CC); 511 } 512 513 if (RETURN_VALUE_USED(opline)) { 514 PZVAL_LOCK(*var_ptr); 515 AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); 516 } 517 FREE_OP2(); 518 519 if (opline->extended_value == ZEND_ASSIGN_DIM) { 520 FREE_OP(free_op_data1); 521 FREE_OP_VAR_PTR(free_op_data2); 522 FREE_OP1_VAR_PTR(); 523 CHECK_EXCEPTION(); 524 ZEND_VM_INC_OPCODE(); 525 } else { 526 FREE_OP1_VAR_PTR(); 527 CHECK_EXCEPTION(); 528 } 529 ZEND_VM_NEXT_OPCODE(); 530} 531 532ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 533{ 534 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, add_function); 535} 536 537ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 538{ 539 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, sub_function); 540} 541 542ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 543{ 544 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mul_function); 545} 546 547ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 548{ 549 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, div_function); 550} 551 552ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 553{ 554 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mod_function); 555} 556 557ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 558{ 559 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_left_function); 560} 561 562ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 563{ 564 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_right_function); 565} 566 567ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 568{ 569 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, concat_function); 570} 571 572ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 573{ 574 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_or_function); 575} 576 577ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 578{ 579 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_and_function); 580} 581 582ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 583{ 584 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_xor_function); 585} 586 587ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, incdec_t incdec_op) 588{ 589 USE_OPLINE 590 zend_free_op free_op1, free_op2; 591 zval **object_ptr; 592 zval *object; 593 zval *property; 594 zval **retval; 595 int have_get_ptr = 0; 596 597 SAVE_OPLINE(); 598 object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); 599 property = GET_OP2_ZVAL_PTR(BP_VAR_R); 600 retval = &EX_T(opline->result.var).var.ptr; 601 602 if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) { 603 zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); 604 } 605 606 make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */ 607 object = *object_ptr; 608 609 if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { 610 zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); 611 FREE_OP2(); 612 if (RETURN_VALUE_USED(opline)) { 613 PZVAL_LOCK(&EG(uninitialized_zval)); 614 *retval = &EG(uninitialized_zval); 615 } 616 FREE_OP1_VAR_PTR(); 617 CHECK_EXCEPTION(); 618 ZEND_VM_NEXT_OPCODE(); 619 } 620 621 /* here we are sure we are dealing with an object */ 622 623 if (IS_OP2_TMP_FREE()) { 624 MAKE_REAL_ZVAL_PTR(property); 625 } 626 627 if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) { 628 zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 629 if (zptr != NULL) { /* NULL means no success in getting PTR */ 630 SEPARATE_ZVAL_IF_NOT_REF(zptr); 631 632 have_get_ptr = 1; 633 incdec_op(*zptr); 634 if (RETURN_VALUE_USED(opline)) { 635 *retval = *zptr; 636 PZVAL_LOCK(*retval); 637 } 638 } 639 } 640 641 if (!have_get_ptr) { 642 if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { 643 zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 644 645 if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { 646 zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); 647 648 if (Z_REFCOUNT_P(z) == 0) { 649 GC_REMOVE_ZVAL_FROM_BUFFER(z); 650 zval_dtor(z); 651 FREE_ZVAL(z); 652 } 653 z = value; 654 } 655 Z_ADDREF_P(z); 656 SEPARATE_ZVAL_IF_NOT_REF(&z); 657 incdec_op(z); 658 *retval = z; 659 Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 660 SELECTIVE_PZVAL_LOCK(*retval, opline); 661 zval_ptr_dtor(&z); 662 } else { 663 zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); 664 if (RETURN_VALUE_USED(opline)) { 665 PZVAL_LOCK(&EG(uninitialized_zval)); 666 *retval = &EG(uninitialized_zval); 667 } 668 } 669 } 670 671 if (IS_OP2_TMP_FREE()) { 672 zval_ptr_dtor(&property); 673 } else { 674 FREE_OP2(); 675 } 676 FREE_OP1_VAR_PTR(); 677 CHECK_EXCEPTION(); 678 ZEND_VM_NEXT_OPCODE(); 679} 680 681ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 682{ 683 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, increment_function); 684} 685 686ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 687{ 688 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, incdec_op, decrement_function); 689} 690 691ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, incdec_t incdec_op) 692{ 693 USE_OPLINE 694 zend_free_op free_op1, free_op2; 695 zval **object_ptr; 696 zval *object; 697 zval *property; 698 zval *retval; 699 int have_get_ptr = 0; 700 701 SAVE_OPLINE(); 702 object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); 703 property = GET_OP2_ZVAL_PTR(BP_VAR_R); 704 retval = &EX_T(opline->result.var).tmp_var; 705 706 if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) { 707 zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); 708 } 709 710 make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */ 711 object = *object_ptr; 712 713 if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { 714 zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); 715 FREE_OP2(); 716 ZVAL_NULL(retval); 717 FREE_OP1_VAR_PTR(); 718 CHECK_EXCEPTION(); 719 ZEND_VM_NEXT_OPCODE(); 720 } 721 722 /* here we are sure we are dealing with an object */ 723 724 if (IS_OP2_TMP_FREE()) { 725 MAKE_REAL_ZVAL_PTR(property); 726 } 727 728 if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) { 729 zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 730 if (zptr != NULL) { /* NULL means no success in getting PTR */ 731 have_get_ptr = 1; 732 SEPARATE_ZVAL_IF_NOT_REF(zptr); 733 734 ZVAL_COPY_VALUE(retval, *zptr); 735 zendi_zval_copy_ctor(*retval); 736 737 incdec_op(*zptr); 738 739 } 740 } 741 742 if (!have_get_ptr) { 743 if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { 744 zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 745 zval *z_copy; 746 747 if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { 748 zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); 749 750 if (Z_REFCOUNT_P(z) == 0) { 751 GC_REMOVE_ZVAL_FROM_BUFFER(z); 752 zval_dtor(z); 753 FREE_ZVAL(z); 754 } 755 z = value; 756 } 757 ZVAL_COPY_VALUE(retval, z); 758 zendi_zval_copy_ctor(*retval); 759 ALLOC_ZVAL(z_copy); 760 INIT_PZVAL_COPY(z_copy, z); 761 zendi_zval_copy_ctor(*z_copy); 762 incdec_op(z_copy); 763 Z_ADDREF_P(z); 764 Z_OBJ_HT_P(object)->write_property(object, property, z_copy, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 765 zval_ptr_dtor(&z_copy); 766 zval_ptr_dtor(&z); 767 } else { 768 zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); 769 ZVAL_NULL(retval); 770 } 771 } 772 773 if (IS_OP2_TMP_FREE()) { 774 zval_ptr_dtor(&property); 775 } else { 776 FREE_OP2(); 777 } 778 FREE_OP1_VAR_PTR(); 779 CHECK_EXCEPTION(); 780 ZEND_VM_NEXT_OPCODE(); 781} 782 783ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 784{ 785 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, increment_function); 786} 787 788ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 789{ 790 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, incdec_op, decrement_function); 791} 792 793ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) 794{ 795 USE_OPLINE 796 zend_free_op free_op1; 797 zval **var_ptr; 798 799 SAVE_OPLINE(); 800 var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); 801 802 if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { 803 zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); 804 } 805 if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { 806 if (RETURN_VALUE_USED(opline)) { 807 PZVAL_LOCK(&EG(uninitialized_zval)); 808 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 809 } 810 FREE_OP1_VAR_PTR(); 811 CHECK_EXCEPTION(); 812 ZEND_VM_NEXT_OPCODE(); 813 } 814 815 SEPARATE_ZVAL_IF_NOT_REF(var_ptr); 816 817 if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT) 818 && Z_OBJ_HANDLER_PP(var_ptr, get) 819 && Z_OBJ_HANDLER_PP(var_ptr, set)) { 820 /* proxy object */ 821 zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC); 822 Z_ADDREF_P(val); 823 fast_increment_function(val); 824 Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC); 825 zval_ptr_dtor(&val); 826 } else { 827 fast_increment_function(*var_ptr); 828 } 829 830 if (RETURN_VALUE_USED(opline)) { 831 PZVAL_LOCK(*var_ptr); 832 AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); 833 } 834 835 FREE_OP1_VAR_PTR(); 836 CHECK_EXCEPTION(); 837 ZEND_VM_NEXT_OPCODE(); 838} 839 840ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY) 841{ 842 USE_OPLINE 843 zend_free_op free_op1; 844 zval **var_ptr; 845 846 SAVE_OPLINE(); 847 var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); 848 849 if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { 850 zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); 851 } 852 if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { 853 if (RETURN_VALUE_USED(opline)) { 854 PZVAL_LOCK(&EG(uninitialized_zval)); 855 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 856 } 857 FREE_OP1_VAR_PTR(); 858 CHECK_EXCEPTION(); 859 ZEND_VM_NEXT_OPCODE(); 860 } 861 862 SEPARATE_ZVAL_IF_NOT_REF(var_ptr); 863 864 if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT) 865 && Z_OBJ_HANDLER_PP(var_ptr, get) 866 && Z_OBJ_HANDLER_PP(var_ptr, set)) { 867 /* proxy object */ 868 zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC); 869 Z_ADDREF_P(val); 870 fast_decrement_function(val); 871 Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC); 872 zval_ptr_dtor(&val); 873 } else { 874 fast_decrement_function(*var_ptr); 875 } 876 877 if (RETURN_VALUE_USED(opline)) { 878 PZVAL_LOCK(*var_ptr); 879 AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); 880 } 881 882 FREE_OP1_VAR_PTR(); 883 CHECK_EXCEPTION(); 884 ZEND_VM_NEXT_OPCODE(); 885} 886 887ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY) 888{ 889 USE_OPLINE 890 zend_free_op free_op1; 891 zval **var_ptr, *retval; 892 893 SAVE_OPLINE(); 894 var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); 895 896 if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { 897 zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); 898 } 899 if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { 900 ZVAL_NULL(&EX_T(opline->result.var).tmp_var); 901 FREE_OP1_VAR_PTR(); 902 CHECK_EXCEPTION(); 903 ZEND_VM_NEXT_OPCODE(); 904 } 905 906 retval = &EX_T(opline->result.var).tmp_var; 907 ZVAL_COPY_VALUE(retval, *var_ptr); 908 zendi_zval_copy_ctor(*retval); 909 910 SEPARATE_ZVAL_IF_NOT_REF(var_ptr); 911 912 if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT) 913 && Z_OBJ_HANDLER_PP(var_ptr, get) 914 && Z_OBJ_HANDLER_PP(var_ptr, set)) { 915 /* proxy object */ 916 zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC); 917 Z_ADDREF_P(val); 918 fast_increment_function(val); 919 Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC); 920 zval_ptr_dtor(&val); 921 } else { 922 fast_increment_function(*var_ptr); 923 } 924 925 FREE_OP1_VAR_PTR(); 926 CHECK_EXCEPTION(); 927 ZEND_VM_NEXT_OPCODE(); 928} 929 930ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY) 931{ 932 USE_OPLINE 933 zend_free_op free_op1; 934 zval **var_ptr, *retval; 935 936 SAVE_OPLINE(); 937 var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); 938 939 if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { 940 zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); 941 } 942 if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { 943 ZVAL_NULL(&EX_T(opline->result.var).tmp_var); 944 FREE_OP1_VAR_PTR(); 945 CHECK_EXCEPTION(); 946 ZEND_VM_NEXT_OPCODE(); 947 } 948 949 retval = &EX_T(opline->result.var).tmp_var; 950 ZVAL_COPY_VALUE(retval, *var_ptr); 951 zendi_zval_copy_ctor(*retval); 952 953 SEPARATE_ZVAL_IF_NOT_REF(var_ptr); 954 955 if (UNEXPECTED(Z_TYPE_PP(var_ptr) == IS_OBJECT) 956 && Z_OBJ_HANDLER_PP(var_ptr, get) 957 && Z_OBJ_HANDLER_PP(var_ptr, set)) { 958 /* proxy object */ 959 zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC); 960 Z_ADDREF_P(val); 961 fast_decrement_function(val); 962 Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC); 963 zval_ptr_dtor(&val); 964 } else { 965 fast_decrement_function(*var_ptr); 966 } 967 968 FREE_OP1_VAR_PTR(); 969 CHECK_EXCEPTION(); 970 ZEND_VM_NEXT_OPCODE(); 971} 972 973ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY) 974{ 975 USE_OPLINE 976 zend_free_op free_op1; 977 zval z_copy; 978 zval *z; 979 980 SAVE_OPLINE(); 981 z = GET_OP1_ZVAL_PTR(BP_VAR_R); 982 983 if (OP1_TYPE != IS_CONST && 984 UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && 985 Z_OBJ_HT_P(z)->get_method != NULL) { 986 if (OP1_TYPE == IS_TMP_VAR) { 987 INIT_PZVAL(z); 988 } 989 if (zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { 990 zend_print_variable(&z_copy); 991 zval_dtor(&z_copy); 992 } else { 993 zend_print_variable(z); 994 } 995 } else { 996 zend_print_variable(z); 997 } 998 999 FREE_OP1(); 1000 CHECK_EXCEPTION(); 1001 ZEND_VM_NEXT_OPCODE(); 1002} 1003 1004ZEND_VM_HANDLER(41, ZEND_PRINT, CONST|TMP|VAR|CV, ANY) 1005{ 1006 USE_OPLINE 1007 1008 ZVAL_LONG(&EX_T(opline->result.var).tmp_var, 1); 1009 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ECHO); 1010} 1011 1012ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|VAR, int type) 1013{ 1014 USE_OPLINE 1015 zend_free_op free_op1; 1016 zval *varname; 1017 zval **retval; 1018 zval tmp_varname; 1019 HashTable *target_symbol_table; 1020 ulong hash_value; 1021 1022 SAVE_OPLINE(); 1023 varname = GET_OP1_ZVAL_PTR(BP_VAR_R); 1024 1025 if (OP1_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) { 1026 ZVAL_COPY_VALUE(&tmp_varname, varname); 1027 zval_copy_ctor(&tmp_varname); 1028 Z_SET_REFCOUNT(tmp_varname, 1); 1029 Z_UNSET_ISREF(tmp_varname); 1030 convert_to_string(&tmp_varname); 1031 varname = &tmp_varname; 1032 } 1033 1034 if (OP2_TYPE != IS_UNUSED) { 1035 zend_class_entry *ce; 1036 1037 if (OP2_TYPE == IS_CONST) { 1038 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 1039 ce = CACHED_PTR(opline->op2.literal->cache_slot); 1040 } else { 1041 ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC); 1042 if (UNEXPECTED(ce == NULL)) { 1043 if (OP1_TYPE != IS_CONST && varname == &tmp_varname) { 1044 zval_dtor(&tmp_varname); 1045 } 1046 FREE_OP1(); 1047 CHECK_EXCEPTION(); 1048 ZEND_VM_NEXT_OPCODE(); 1049 } 1050 CACHE_PTR(opline->op2.literal->cache_slot, ce); 1051 } 1052 } else { 1053 ce = EX_T(opline->op2.var).class_entry; 1054 } 1055 retval = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0, ((OP1_TYPE == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); 1056 FREE_OP1(); 1057 } else { 1058 target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); 1059/* 1060 if (!target_symbol_table) { 1061 CHECK_EXCEPTION(); 1062 ZEND_VM_NEXT_OPCODE(); 1063 } 1064*/ 1065 if (OP1_TYPE == IS_CONST) { 1066 hash_value = Z_HASH_P(varname); 1067 } else if (IS_INTERNED(Z_STRVAL_P(varname))) { 1068 hash_value = INTERNED_HASH(Z_STRVAL_P(varname)); 1069 } else { 1070 hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1); 1071 } 1072 1073 if (zend_hash_quick_find(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, (void **) &retval) == FAILURE) { 1074 switch (type) { 1075 case BP_VAR_R: 1076 case BP_VAR_UNSET: 1077 zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); 1078 /* break missing intentionally */ 1079 case BP_VAR_IS: 1080 retval = &EG(uninitialized_zval_ptr); 1081 break; 1082 case BP_VAR_RW: 1083 zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); 1084 /* break missing intentionally */ 1085 case BP_VAR_W: 1086 Z_ADDREF_P(&EG(uninitialized_zval)); 1087 zend_hash_quick_update(target_symbol_table, Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1, hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **) &retval); 1088 break; 1089 EMPTY_SWITCH_DEFAULT_CASE() 1090 } 1091 } 1092 switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) { 1093 case ZEND_FETCH_GLOBAL: 1094 if (OP1_TYPE != IS_TMP_VAR) { 1095 FREE_OP1(); 1096 } 1097 break; 1098 case ZEND_FETCH_LOCAL: 1099 FREE_OP1(); 1100 break; 1101 case ZEND_FETCH_STATIC: 1102 zval_update_constant(retval, (void*) 1 TSRMLS_CC); 1103 break; 1104 case ZEND_FETCH_GLOBAL_LOCK: 1105 if (OP1_TYPE == IS_VAR && !free_op1.var) { 1106 PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); 1107 } 1108 break; 1109 } 1110 } 1111 1112 1113 if (OP1_TYPE != IS_CONST && varname == &tmp_varname) { 1114 zval_dtor(&tmp_varname); 1115 } 1116 if (opline->extended_value & ZEND_FETCH_MAKE_REF) { 1117 SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); 1118 } 1119 PZVAL_LOCK(*retval); 1120 switch (type) { 1121 case BP_VAR_R: 1122 case BP_VAR_IS: 1123 AI_SET_PTR(&EX_T(opline->result.var), *retval); 1124 break; 1125 case BP_VAR_UNSET: { 1126 zend_free_op free_res; 1127 1128 PZVAL_UNLOCK(*retval, &free_res); 1129 if (retval != &EG(uninitialized_zval_ptr)) { 1130 SEPARATE_ZVAL_IF_NOT_REF(retval); 1131 } 1132 PZVAL_LOCK(*retval); 1133 FREE_OP_VAR_PTR(free_res); 1134 } 1135 /* break missing intentionally */ 1136 default: 1137 EX_T(opline->result.var).var.ptr_ptr = retval; 1138 break; 1139 } 1140 CHECK_EXCEPTION(); 1141 ZEND_VM_NEXT_OPCODE(); 1142} 1143 1144ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) 1145{ 1146 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R); 1147} 1148 1149ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) 1150{ 1151 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W); 1152} 1153 1154ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) 1155{ 1156 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_RW); 1157} 1158 1159ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) 1160{ 1161 USE_OPLINE 1162 1163 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, 1164 ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R); 1165} 1166 1167ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) 1168{ 1169 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_UNSET); 1170} 1171 1172ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) 1173{ 1174 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS); 1175} 1176 1177ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 1178{ 1179 USE_OPLINE 1180 zend_free_op free_op1, free_op2; 1181 zval **container; 1182 1183 SAVE_OPLINE(); 1184 1185 if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && 1186 OP1_TYPE != IS_CV && 1187 EX_T(opline->op1.var).var.ptr_ptr) { 1188 PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); 1189 } 1190 1191 if (OP1_TYPE == IS_TMP_VAR || OP1_TYPE == IS_CONST) { 1192 zval *container = GET_OP1_ZVAL_PTR(BP_VAR_R); 1193 zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); 1194 FREE_OP2(); 1195 FREE_OP1(); 1196 } else { 1197 container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R); 1198 zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); 1199 FREE_OP2(); 1200 FREE_OP1_VAR_PTR(); 1201 } 1202 1203 CHECK_EXCEPTION(); 1204 ZEND_VM_NEXT_OPCODE(); 1205} 1206 1207ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV) 1208{ 1209 USE_OPLINE 1210 zend_free_op free_op1, free_op2; 1211 zval **container; 1212 1213 SAVE_OPLINE(); 1214 container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); 1215 1216 if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { 1217 zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); 1218 } 1219 zend_fetch_dimension_address(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_W TSRMLS_CC); 1220 FREE_OP2(); 1221 if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { 1222 EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); 1223 } 1224 FREE_OP1_VAR_PTR(); 1225 1226 /* We are going to assign the result by reference */ 1227 if (UNEXPECTED(opline->extended_value != 0)) { 1228 zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr; 1229 1230 if (retval_ptr) { 1231 Z_DELREF_PP(retval_ptr); 1232 SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr); 1233 Z_ADDREF_PP(retval_ptr); 1234 } 1235 } 1236 1237 CHECK_EXCEPTION(); 1238 ZEND_VM_NEXT_OPCODE(); 1239} 1240 1241ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV) 1242{ 1243 USE_OPLINE 1244 zend_free_op free_op1, free_op2; 1245 zval **container; 1246 1247 SAVE_OPLINE(); 1248 container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); 1249 1250 if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { 1251 zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); 1252 } 1253 zend_fetch_dimension_address(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_RW TSRMLS_CC); 1254 FREE_OP2(); 1255 if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { 1256 EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); 1257 } 1258 FREE_OP1_VAR_PTR(); 1259 CHECK_EXCEPTION(); 1260 ZEND_VM_NEXT_OPCODE(); 1261} 1262 1263ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV) 1264{ 1265 USE_OPLINE 1266 zend_free_op free_op1, free_op2; 1267 zval **container; 1268 1269 SAVE_OPLINE(); 1270 container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS); 1271 zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_IS TSRMLS_CC); 1272 FREE_OP2(); 1273 FREE_OP1_VAR_PTR(); 1274 CHECK_EXCEPTION(); 1275 ZEND_VM_NEXT_OPCODE(); 1276} 1277 1278ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV) 1279{ 1280 USE_OPLINE 1281 zend_free_op free_op1, free_op2; 1282 zval **container; 1283 1284 SAVE_OPLINE(); 1285 1286 if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) { 1287 container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); 1288 if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { 1289 zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); 1290 } 1291 zend_fetch_dimension_address(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_W TSRMLS_CC); 1292 if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { 1293 EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); 1294 } 1295 } else { 1296 if (OP2_TYPE == IS_UNUSED) { 1297 zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); 1298 } 1299 container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R); 1300 zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); 1301 } 1302 FREE_OP2(); 1303 FREE_OP1_VAR_PTR(); 1304 CHECK_EXCEPTION(); 1305 ZEND_VM_NEXT_OPCODE(); 1306} 1307 1308ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV) 1309{ 1310 USE_OPLINE 1311 zend_free_op free_op1, free_op2; 1312 zval **container; 1313 1314 SAVE_OPLINE(); 1315 container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_UNSET); 1316 1317 if (OP1_TYPE == IS_CV) { 1318 if (container != &EG(uninitialized_zval_ptr)) { 1319 SEPARATE_ZVAL_IF_NOT_REF(container); 1320 } 1321 } 1322 if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { 1323 zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); 1324 } 1325 zend_fetch_dimension_address(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_UNSET TSRMLS_CC); 1326 FREE_OP2(); 1327 if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { 1328 EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); 1329 } 1330 FREE_OP1_VAR_PTR(); 1331 if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) { 1332 zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); 1333 } else { 1334 zend_free_op free_res; 1335 zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr; 1336 1337 PZVAL_UNLOCK(*retval_ptr, &free_res); 1338 if (retval_ptr != &EG(uninitialized_zval_ptr)) { 1339 SEPARATE_ZVAL_IF_NOT_REF(retval_ptr); 1340 } 1341 PZVAL_LOCK(*retval_ptr); 1342 FREE_OP_VAR_PTR(free_res); 1343 CHECK_EXCEPTION(); 1344 ZEND_VM_NEXT_OPCODE(); 1345 } 1346} 1347 1348ZEND_VM_HELPER(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 1349{ 1350 USE_OPLINE 1351 zend_free_op free_op1; 1352 zval *container; 1353 zend_free_op free_op2; 1354 zval *offset; 1355 1356 SAVE_OPLINE(); 1357 container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R); 1358 offset = GET_OP2_ZVAL_PTR(BP_VAR_R); 1359 1360 if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || 1361 UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { 1362 zend_error(E_NOTICE, "Trying to get property of non-object"); 1363 PZVAL_LOCK(&EG(uninitialized_zval)); 1364 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 1365 FREE_OP2(); 1366 } else { 1367 zval *retval; 1368 1369 if (IS_OP2_TMP_FREE()) { 1370 MAKE_REAL_ZVAL_PTR(offset); 1371 } 1372 1373 /* here we are sure we are dealing with an object */ 1374 retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 1375 1376 PZVAL_LOCK(retval); 1377 AI_SET_PTR(&EX_T(opline->result.var), retval); 1378 1379 if (IS_OP2_TMP_FREE()) { 1380 zval_ptr_dtor(&offset); 1381 } else { 1382 FREE_OP2(); 1383 } 1384 } 1385 1386 FREE_OP1(); 1387 CHECK_EXCEPTION(); 1388 ZEND_VM_NEXT_OPCODE(); 1389} 1390 1391ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 1392{ 1393 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_property_address_read_helper); 1394} 1395 1396ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 1397{ 1398 USE_OPLINE 1399 zend_free_op free_op1, free_op2; 1400 zval *property; 1401 zval **container; 1402 1403 SAVE_OPLINE(); 1404 property = GET_OP2_ZVAL_PTR(BP_VAR_R); 1405 1406 if (OP1_TYPE == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 1407 PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); 1408 EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; 1409 } 1410 1411 if (IS_OP2_TMP_FREE()) { 1412 MAKE_REAL_ZVAL_PTR(property); 1413 } 1414 container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W); 1415 if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { 1416 zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); 1417 } 1418 1419 zend_fetch_property_address(&EX_T(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), BP_VAR_W TSRMLS_CC); 1420 if (IS_OP2_TMP_FREE()) { 1421 zval_ptr_dtor(&property); 1422 } else { 1423 FREE_OP2(); 1424 } 1425 if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { 1426 EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); 1427 } 1428 FREE_OP1_VAR_PTR(); 1429 1430 /* We are going to assign the result by reference */ 1431 if (opline->extended_value & ZEND_FETCH_MAKE_REF) { 1432 zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr; 1433 1434 Z_DELREF_PP(retval_ptr); 1435 SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr); 1436 Z_ADDREF_PP(retval_ptr); 1437 EX_T(opline->result.var).var.ptr = *EX_T(opline->result.var).var.ptr_ptr; 1438 EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; 1439 } 1440 1441 CHECK_EXCEPTION(); 1442 ZEND_VM_NEXT_OPCODE(); 1443} 1444 1445ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 1446{ 1447 USE_OPLINE 1448 zend_free_op free_op1, free_op2; 1449 zval *property; 1450 zval **container; 1451 1452 SAVE_OPLINE(); 1453 property = GET_OP2_ZVAL_PTR(BP_VAR_R); 1454 container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); 1455 1456 if (IS_OP2_TMP_FREE()) { 1457 MAKE_REAL_ZVAL_PTR(property); 1458 } 1459 if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { 1460 zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); 1461 } 1462 zend_fetch_property_address(&EX_T(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), BP_VAR_RW TSRMLS_CC); 1463 if (IS_OP2_TMP_FREE()) { 1464 zval_ptr_dtor(&property); 1465 } else { 1466 FREE_OP2(); 1467 } 1468 if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { 1469 EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); 1470 } 1471 FREE_OP1_VAR_PTR(); 1472 CHECK_EXCEPTION(); 1473 ZEND_VM_NEXT_OPCODE(); 1474} 1475 1476ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 1477{ 1478 USE_OPLINE 1479 zend_free_op free_op1; 1480 zval *container; 1481 zend_free_op free_op2; 1482 zval *offset; 1483 1484 SAVE_OPLINE(); 1485 container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS); 1486 offset = GET_OP2_ZVAL_PTR(BP_VAR_R); 1487 1488 if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || 1489 UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { 1490 PZVAL_LOCK(&EG(uninitialized_zval)); 1491 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 1492 FREE_OP2(); 1493 } else { 1494 zval *retval; 1495 1496 if (IS_OP2_TMP_FREE()) { 1497 MAKE_REAL_ZVAL_PTR(offset); 1498 } 1499 1500 /* here we are sure we are dealing with an object */ 1501 retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 1502 1503 PZVAL_LOCK(retval); 1504 AI_SET_PTR(&EX_T(opline->result.var), retval); 1505 1506 if (IS_OP2_TMP_FREE()) { 1507 zval_ptr_dtor(&offset); 1508 } else { 1509 FREE_OP2(); 1510 } 1511 } 1512 1513 FREE_OP1(); 1514 CHECK_EXCEPTION(); 1515 ZEND_VM_NEXT_OPCODE(); 1516} 1517 1518ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 1519{ 1520 USE_OPLINE 1521 1522 if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) { 1523 /* Behave like FETCH_OBJ_W */ 1524 zend_free_op free_op1, free_op2; 1525 zval *property; 1526 zval **container; 1527 1528 SAVE_OPLINE(); 1529 property = GET_OP2_ZVAL_PTR(BP_VAR_R); 1530 container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W); 1531 1532 if (IS_OP2_TMP_FREE()) { 1533 MAKE_REAL_ZVAL_PTR(property); 1534 } 1535 if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { 1536 zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); 1537 } 1538 zend_fetch_property_address(&EX_T(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), BP_VAR_W TSRMLS_CC); 1539 if (IS_OP2_TMP_FREE()) { 1540 zval_ptr_dtor(&property); 1541 } else { 1542 FREE_OP2(); 1543 } 1544 if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { 1545 EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); 1546 } 1547 FREE_OP1_VAR_PTR(); 1548 CHECK_EXCEPTION(); 1549 ZEND_VM_NEXT_OPCODE(); 1550 } else { 1551 ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_property_address_read_helper); 1552 } 1553} 1554 1555ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 1556{ 1557 USE_OPLINE 1558 zend_free_op free_op1, free_op2, free_res; 1559 zval **container; 1560 zval *property; 1561 1562 SAVE_OPLINE(); 1563 container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET); 1564 property = GET_OP2_ZVAL_PTR(BP_VAR_R); 1565 1566 if (OP1_TYPE == IS_CV) { 1567 if (container != &EG(uninitialized_zval_ptr)) { 1568 SEPARATE_ZVAL_IF_NOT_REF(container); 1569 } 1570 } 1571 if (IS_OP2_TMP_FREE()) { 1572 MAKE_REAL_ZVAL_PTR(property); 1573 } 1574 if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { 1575 zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); 1576 } 1577 zend_fetch_property_address(&EX_T(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL), BP_VAR_UNSET TSRMLS_CC); 1578 if (IS_OP2_TMP_FREE()) { 1579 zval_ptr_dtor(&property); 1580 } else { 1581 FREE_OP2(); 1582 } 1583 if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { 1584 EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); 1585 } 1586 FREE_OP1_VAR_PTR(); 1587 1588 PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res); 1589 if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) { 1590 SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.var).var.ptr_ptr); 1591 } 1592 PZVAL_LOCK(*EX_T(opline->result.var).var.ptr_ptr); 1593 FREE_OP_VAR_PTR(free_res); 1594 CHECK_EXCEPTION(); 1595 ZEND_VM_NEXT_OPCODE(); 1596} 1597 1598ZEND_VM_HANDLER(98, ZEND_FETCH_DIM_TMP_VAR, CONST|TMP, CONST) 1599{ 1600 USE_OPLINE 1601 zend_free_op free_op1; 1602 zval *container; 1603 1604 SAVE_OPLINE(); 1605 container = GET_OP1_ZVAL_PTR(BP_VAR_R); 1606 1607 if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) { 1608 PZVAL_LOCK(&EG(uninitialized_zval)); 1609 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 1610 } else { 1611 zend_free_op free_op2; 1612 zval *value = *zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); 1613 1614 PZVAL_LOCK(value); 1615 AI_SET_PTR(&EX_T(opline->result.var), value); 1616 FREE_OP2(); 1617 } 1618 CHECK_EXCEPTION(); 1619 ZEND_VM_NEXT_OPCODE(); 1620} 1621 1622ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 1623{ 1624 USE_OPLINE 1625 zend_free_op free_op1, free_op2; 1626 zval **object_ptr; 1627 zval *property_name; 1628 1629 SAVE_OPLINE(); 1630 object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W); 1631 property_name = GET_OP2_ZVAL_PTR(BP_VAR_R); 1632 1633 if (IS_OP2_TMP_FREE()) { 1634 MAKE_REAL_ZVAL_PTR(property_name); 1635 } 1636 if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) { 1637 zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); 1638 } 1639 zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 1640 if (IS_OP2_TMP_FREE()) { 1641 zval_ptr_dtor(&property_name); 1642 } else { 1643 FREE_OP2(); 1644 } 1645 FREE_OP1_VAR_PTR(); 1646 /* assign_obj has two opcodes! */ 1647 CHECK_EXCEPTION(); 1648 ZEND_VM_INC_OPCODE(); 1649 ZEND_VM_NEXT_OPCODE(); 1650} 1651 1652ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV) 1653{ 1654 USE_OPLINE 1655 zend_free_op free_op1; 1656 zval **object_ptr; 1657 1658 SAVE_OPLINE(); 1659 object_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); 1660 1661 if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) { 1662 zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); 1663 } 1664 if (Z_TYPE_PP(object_ptr) == IS_OBJECT) { 1665 zend_free_op free_op2; 1666 zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R); 1667 1668 if (IS_OP2_TMP_FREE()) { 1669 MAKE_REAL_ZVAL_PTR(property_name); 1670 } 1671 zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 1672 if (IS_OP2_TMP_FREE()) { 1673 zval_ptr_dtor(&property_name); 1674 } else { 1675 FREE_OP2(); 1676 } 1677 } else { 1678 zend_free_op free_op2, free_op_data1, free_op_data2; 1679 zval *value; 1680 zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R); 1681 zval **variable_ptr_ptr; 1682 1683 zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, OP2_TYPE, BP_VAR_W TSRMLS_CC); 1684 FREE_OP2(); 1685 1686 value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R); 1687 variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC); 1688 if (UNEXPECTED(variable_ptr_ptr == NULL)) { 1689 if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) { 1690 if (RETURN_VALUE_USED(opline)) { 1691 zval *retval; 1692 1693 ALLOC_ZVAL(retval); 1694 ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); 1695 INIT_PZVAL(retval); 1696 AI_SET_PTR(&EX_T(opline->result.var), retval); 1697 } 1698 } else if (RETURN_VALUE_USED(opline)) { 1699 PZVAL_LOCK(&EG(uninitialized_zval)); 1700 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 1701 } 1702 } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { 1703 if (IS_TMP_FREE(free_op_data1)) { 1704 zval_dtor(value); 1705 } 1706 if (RETURN_VALUE_USED(opline)) { 1707 PZVAL_LOCK(&EG(uninitialized_zval)); 1708 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 1709 } 1710 } else { 1711 if ((opline+1)->op1_type == IS_TMP_VAR) { 1712 value = zend_assign_tmp_to_variable(variable_ptr_ptr, value TSRMLS_CC); 1713 } else if ((opline+1)->op1_type == IS_CONST) { 1714 value = zend_assign_const_to_variable(variable_ptr_ptr, value TSRMLS_CC); 1715 } else { 1716 value = zend_assign_to_variable(variable_ptr_ptr, value TSRMLS_CC); 1717 } 1718 if (RETURN_VALUE_USED(opline)) { 1719 PZVAL_LOCK(value); 1720 AI_SET_PTR(&EX_T(opline->result.var), value); 1721 } 1722 } 1723 FREE_OP_VAR_PTR(free_op_data2); 1724 FREE_OP_IF_VAR(free_op_data1); 1725 } 1726 FREE_OP1_VAR_PTR(); 1727 /* assign_dim has two opcodes! */ 1728 CHECK_EXCEPTION(); 1729 ZEND_VM_INC_OPCODE(); 1730 ZEND_VM_NEXT_OPCODE(); 1731} 1732 1733ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV) 1734{ 1735 USE_OPLINE 1736 zend_free_op free_op1, free_op2; 1737 zval *value; 1738 zval **variable_ptr_ptr; 1739 1740 SAVE_OPLINE(); 1741 value = GET_OP2_ZVAL_PTR(BP_VAR_R); 1742 variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); 1743 1744 if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) { 1745 if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, OP2_TYPE TSRMLS_CC)) { 1746 if (RETURN_VALUE_USED(opline)) { 1747 zval *retval; 1748 1749 ALLOC_ZVAL(retval); 1750 ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); 1751 INIT_PZVAL(retval); 1752 AI_SET_PTR(&EX_T(opline->result.var), retval); 1753 } 1754 } else if (RETURN_VALUE_USED(opline)) { 1755 PZVAL_LOCK(&EG(uninitialized_zval)); 1756 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 1757 } 1758 } else if (OP1_TYPE == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { 1759 if (IS_OP2_TMP_FREE()) { 1760 zval_dtor(value); 1761 } 1762 if (RETURN_VALUE_USED(opline)) { 1763 PZVAL_LOCK(&EG(uninitialized_zval)); 1764 AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); 1765 } 1766 } else { 1767 if (OP2_TYPE == IS_TMP_VAR) { 1768 value = zend_assign_tmp_to_variable(variable_ptr_ptr, value TSRMLS_CC); 1769 } else if (OP2_TYPE == IS_CONST) { 1770 value = zend_assign_const_to_variable(variable_ptr_ptr, value TSRMLS_CC); 1771 } else { 1772 value = zend_assign_to_variable(variable_ptr_ptr, value TSRMLS_CC); 1773 } 1774 if (RETURN_VALUE_USED(opline)) { 1775 PZVAL_LOCK(value); 1776 AI_SET_PTR(&EX_T(opline->result.var), value); 1777 } 1778 } 1779 1780 FREE_OP1_VAR_PTR(); 1781 1782 /* zend_assign_to_variable() always takes care of op2, never free it! */ 1783 FREE_OP2_IF_VAR(); 1784 1785 CHECK_EXCEPTION(); 1786 ZEND_VM_NEXT_OPCODE(); 1787} 1788 1789ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) 1790{ 1791 USE_OPLINE 1792 zend_free_op free_op1, free_op2; 1793 zval **variable_ptr_ptr; 1794 zval **value_ptr_ptr; 1795 1796 SAVE_OPLINE(); 1797 value_ptr_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W); 1798 1799 if (OP2_TYPE == IS_VAR && 1800 value_ptr_ptr && 1801 !Z_ISREF_PP(value_ptr_ptr) && 1802 opline->extended_value == ZEND_RETURNS_FUNCTION && 1803 !EX_T(opline->op2.var).var.fcall_returned_reference) { 1804 if (free_op2.var == NULL) { 1805 PZVAL_LOCK(*value_ptr_ptr); /* undo the effect of get_zval_ptr_ptr() */ 1806 } 1807 zend_error(E_STRICT, "Only variables should be assigned by reference"); 1808 if (UNEXPECTED(EG(exception) != NULL)) { 1809 FREE_OP2_VAR_PTR(); 1810 HANDLE_EXCEPTION(); 1811 } 1812 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN); 1813 } else if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { 1814 PZVAL_LOCK(*value_ptr_ptr); 1815 } 1816 if (OP1_TYPE == IS_VAR && UNEXPECTED(EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr)) { 1817 zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); 1818 } 1819 1820 variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); 1821 if ((OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) || 1822 (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) { 1823 zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); 1824 } 1825 zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC); 1826 1827 if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { 1828 Z_DELREF_PP(variable_ptr_ptr); 1829 } 1830 1831 if (RETURN_VALUE_USED(opline)) { 1832 PZVAL_LOCK(*variable_ptr_ptr); 1833 AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr); 1834 } 1835 1836 FREE_OP1_VAR_PTR(); 1837 FREE_OP2_VAR_PTR(); 1838 1839 CHECK_EXCEPTION(); 1840 ZEND_VM_NEXT_OPCODE(); 1841} 1842 1843ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY) 1844{ 1845 USE_OPLINE 1846 1847#if DEBUG_ZEND>=2 1848 printf("Jumping to %d\n", opline->op1.opline_num); 1849#endif 1850 ZEND_VM_SET_OPCODE(opline->op1.jmp_addr); 1851 ZEND_VM_CONTINUE(); /* CHECK_ME */ 1852} 1853 1854ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY) 1855{ 1856 USE_OPLINE 1857 zend_free_op free_op1; 1858 zval *val; 1859 int ret; 1860 1861 SAVE_OPLINE(); 1862 val = GET_OP1_ZVAL_PTR(BP_VAR_R); 1863 1864 if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { 1865 ret = Z_LVAL_P(val); 1866 } else { 1867 ret = i_zend_is_true(val); 1868 FREE_OP1(); 1869 if (UNEXPECTED(EG(exception) != NULL)) { 1870 HANDLE_EXCEPTION(); 1871 } 1872 } 1873 if (!ret) { 1874#if DEBUG_ZEND>=2 1875 printf("Conditional jmp to %d\n", opline->op2.opline_num); 1876#endif 1877 ZEND_VM_SET_OPCODE(opline->op2.jmp_addr); 1878 ZEND_VM_CONTINUE(); 1879 } 1880 1881 ZEND_VM_NEXT_OPCODE(); 1882} 1883 1884ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMP|VAR|CV, ANY) 1885{ 1886 USE_OPLINE 1887 zend_free_op free_op1; 1888 zval *val; 1889 int ret; 1890 1891 SAVE_OPLINE(); 1892 val = GET_OP1_ZVAL_PTR(BP_VAR_R); 1893 1894 if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { 1895 ret = Z_LVAL_P(val); 1896 } else { 1897 ret = i_zend_is_true(val); 1898 FREE_OP1(); 1899 if (UNEXPECTED(EG(exception) != NULL)) { 1900 HANDLE_EXCEPTION(); 1901 } 1902 } 1903 if (ret) { 1904#if DEBUG_ZEND>=2 1905 printf("Conditional jmp to %d\n", opline->op2.opline_num); 1906#endif 1907 ZEND_VM_SET_OPCODE(opline->op2.jmp_addr); 1908 ZEND_VM_CONTINUE(); 1909 } 1910 1911 ZEND_VM_NEXT_OPCODE(); 1912} 1913 1914ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMP|VAR|CV, ANY) 1915{ 1916 USE_OPLINE 1917 zend_free_op free_op1; 1918 zval *val; 1919 int retval; 1920 1921 SAVE_OPLINE(); 1922 val = GET_OP1_ZVAL_PTR(BP_VAR_R); 1923 1924 if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { 1925 retval = Z_LVAL_P(val); 1926 } else { 1927 retval = i_zend_is_true(val); 1928 FREE_OP1(); 1929 if (UNEXPECTED(EG(exception) != NULL)) { 1930 HANDLE_EXCEPTION(); 1931 } 1932 } 1933 if (EXPECTED(retval != 0)) { 1934#if DEBUG_ZEND>=2 1935 printf("Conditional jmp on true to %d\n", opline->extended_value); 1936#endif 1937 ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]); 1938 ZEND_VM_CONTINUE(); /* CHECK_ME */ 1939 } else { 1940#if DEBUG_ZEND>=2 1941 printf("Conditional jmp on false to %d\n", opline->op2.opline_num); 1942#endif 1943 ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]); 1944 ZEND_VM_CONTINUE(); /* CHECK_ME */ 1945 } 1946} 1947 1948ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMP|VAR|CV, ANY) 1949{ 1950 USE_OPLINE 1951 zend_free_op free_op1; 1952 zval *val; 1953 int retval; 1954 1955 SAVE_OPLINE(); 1956 val = GET_OP1_ZVAL_PTR(BP_VAR_R); 1957 1958 if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { 1959 retval = Z_LVAL_P(val); 1960 } else { 1961 retval = i_zend_is_true(val); 1962 FREE_OP1(); 1963 if (UNEXPECTED(EG(exception) != NULL)) { 1964 HANDLE_EXCEPTION(); 1965 } 1966 } 1967 Z_LVAL(EX_T(opline->result.var).tmp_var) = retval; 1968 Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL; 1969 if (!retval) { 1970#if DEBUG_ZEND>=2 1971 printf("Conditional jmp to %d\n", opline->op2.opline_num); 1972#endif 1973 ZEND_VM_SET_OPCODE(opline->op2.jmp_addr); 1974 ZEND_VM_CONTINUE(); 1975 } 1976 ZEND_VM_NEXT_OPCODE(); 1977} 1978 1979ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMP|VAR|CV, ANY) 1980{ 1981 USE_OPLINE 1982 zend_free_op free_op1; 1983 zval *val; 1984 int retval; 1985 1986 SAVE_OPLINE(); 1987 val = GET_OP1_ZVAL_PTR(BP_VAR_R); 1988 1989 if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { 1990 retval = Z_LVAL_P(val); 1991 } else { 1992 retval = i_zend_is_true(val); 1993 FREE_OP1(); 1994 if (UNEXPECTED(EG(exception) != NULL)) { 1995 HANDLE_EXCEPTION(); 1996 } 1997 } 1998 Z_LVAL(EX_T(opline->result.var).tmp_var) = retval; 1999 Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL; 2000 if (retval) { 2001#if DEBUG_ZEND>=2 2002 printf("Conditional jmp to %d\n", opline->op2.opline_num); 2003#endif 2004 ZEND_VM_SET_OPCODE(opline->op2.jmp_addr); 2005 ZEND_VM_CONTINUE(); 2006 } 2007 ZEND_VM_NEXT_OPCODE(); 2008} 2009 2010ZEND_VM_HANDLER(70, ZEND_FREE, TMP|VAR, ANY) 2011{ 2012 USE_OPLINE 2013 2014 SAVE_OPLINE(); 2015 if (OP1_TYPE == IS_TMP_VAR) { 2016 zendi_zval_dtor(EX_T(opline->op1.var).tmp_var); 2017 } else { 2018 zval_ptr_dtor(&EX_T(opline->op1.var).var.ptr); 2019 } 2020 CHECK_EXCEPTION(); 2021 ZEND_VM_NEXT_OPCODE(); 2022} 2023 2024ZEND_VM_HANDLER(53, ZEND_INIT_STRING, ANY, ANY) 2025{ 2026 USE_OPLINE 2027 zval *tmp = &EX_T(opline->result.var).tmp_var; 2028 2029 SAVE_OPLINE(); 2030 tmp->value.str.val = emalloc(1); 2031 tmp->value.str.val[0] = 0; 2032 tmp->value.str.len = 0; 2033 Z_SET_REFCOUNT_P(tmp, 1); 2034 tmp->type = IS_STRING; 2035 Z_UNSET_ISREF_P(tmp); 2036 /*CHECK_EXCEPTION();*/ 2037 ZEND_VM_NEXT_OPCODE(); 2038} 2039 2040ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP|UNUSED, CONST) 2041{ 2042 USE_OPLINE 2043 zval *str = &EX_T(opline->result.var).tmp_var; 2044 2045 SAVE_OPLINE(); 2046 2047 if (OP1_TYPE == IS_UNUSED) { 2048 /* Initialize for erealloc in add_char_to_string */ 2049 Z_STRVAL_P(str) = NULL; 2050 Z_STRLEN_P(str) = 0; 2051 Z_TYPE_P(str) = IS_STRING; 2052 2053 INIT_PZVAL(str); 2054 } 2055 2056 add_char_to_string(str, str, opline->op2.zv); 2057 2058 /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */ 2059 /*CHECK_EXCEPTION();*/ 2060 ZEND_VM_NEXT_OPCODE(); 2061} 2062 2063ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP|UNUSED, CONST) 2064{ 2065 USE_OPLINE 2066 zval *str = &EX_T(opline->result.var).tmp_var; 2067 2068 SAVE_OPLINE(); 2069 2070 if (OP1_TYPE == IS_UNUSED) { 2071 /* Initialize for erealloc in add_string_to_string */ 2072 Z_STRVAL_P(str) = NULL; 2073 Z_STRLEN_P(str) = 0; 2074 Z_TYPE_P(str) = IS_STRING; 2075 2076 INIT_PZVAL(str); 2077 } 2078 2079 add_string_to_string(str, str, opline->op2.zv); 2080 2081 /* FREE_OP is missing intentionally here - we're always working on the same temporary variable */ 2082 /*CHECK_EXCEPTION();*/ 2083 ZEND_VM_NEXT_OPCODE(); 2084} 2085 2086ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP|UNUSED, TMP|VAR|CV) 2087{ 2088 USE_OPLINE 2089 zend_free_op free_op2; 2090 zval *str = &EX_T(opline->result.var).tmp_var; 2091 zval *var; 2092 zval var_copy; 2093 int use_copy = 0; 2094 2095 SAVE_OPLINE(); 2096 var = GET_OP2_ZVAL_PTR(BP_VAR_R); 2097 2098 if (OP1_TYPE == IS_UNUSED) { 2099 /* Initialize for erealloc in add_string_to_string */ 2100 Z_STRVAL_P(str) = NULL; 2101 Z_STRLEN_P(str) = 0; 2102 Z_TYPE_P(str) = IS_STRING; 2103 2104 INIT_PZVAL(str); 2105 } 2106 2107 if (Z_TYPE_P(var) != IS_STRING) { 2108 zend_make_printable_zval(var, &var_copy, &use_copy); 2109 2110 if (use_copy) { 2111 var = &var_copy; 2112 } 2113 } 2114 add_string_to_string(str, str, var); 2115 2116 if (use_copy) { 2117 zval_dtor(var); 2118 } 2119 /* original comment, possibly problematic: 2120 * FREE_OP is missing intentionally here - we're always working on the same temporary variable 2121 * (Zeev): I don't think it's problematic, we only use variables 2122 * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're 2123 * string offsets or overloaded objects 2124 */ 2125 FREE_OP2(); 2126 2127 CHECK_EXCEPTION(); 2128 ZEND_VM_NEXT_OPCODE(); 2129} 2130 2131ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV) 2132{ 2133 USE_OPLINE 2134 2135 SAVE_OPLINE(); 2136 EG(exception) = NULL; 2137 if (OP2_TYPE == IS_UNUSED) { 2138 EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC); 2139 CHECK_EXCEPTION(); 2140 ZEND_VM_NEXT_OPCODE(); 2141 } else { 2142 zend_free_op free_op2; 2143 zval *class_name = GET_OP2_ZVAL_PTR(BP_VAR_R); 2144 2145 if (OP2_TYPE == IS_CONST) { 2146 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 2147 EX_T(opline->result.var).class_entry = CACHED_PTR(opline->op2.literal->cache_slot); 2148 } else { 2149 EX_T(opline->result.var).class_entry = zend_fetch_class_by_name(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->op2.literal + 1, opline->extended_value TSRMLS_CC); 2150 CACHE_PTR(opline->op2.literal->cache_slot, EX_T(opline->result.var).class_entry); 2151 } 2152 } else if (Z_TYPE_P(class_name) == IS_OBJECT) { 2153 EX_T(opline->result.var).class_entry = Z_OBJCE_P(class_name); 2154 } else if (Z_TYPE_P(class_name) == IS_STRING) { 2155 EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC); 2156 } else { 2157 zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); 2158 } 2159 2160 FREE_OP2(); 2161 CHECK_EXCEPTION(); 2162 ZEND_VM_NEXT_OPCODE(); 2163 } 2164} 2165 2166ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) 2167{ 2168 USE_OPLINE 2169 zval *function_name; 2170 char *function_name_strval; 2171 int function_name_strlen; 2172 zend_free_op free_op1, free_op2; 2173 2174 SAVE_OPLINE(); 2175 zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); 2176 2177 function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); 2178 2179 if (OP2_TYPE != IS_CONST && 2180 UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { 2181 zend_error_noreturn(E_ERROR, "Method name must be a string"); 2182 } 2183 2184 function_name_strval = Z_STRVAL_P(function_name); 2185 function_name_strlen = Z_STRLEN_P(function_name); 2186 2187 EX(object) = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R); 2188 2189 if (EXPECTED(EX(object) != NULL) && 2190 EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) { 2191 EX(called_scope) = Z_OBJCE_P(EX(object)); 2192 2193 if (OP2_TYPE != IS_CONST || 2194 (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) { 2195 zval *object = EX(object); 2196 2197 if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) { 2198 zend_error_noreturn(E_ERROR, "Object does not support method calls"); 2199 } 2200 2201 /* First, locate the function. */ 2202 EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((OP2_TYPE == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC); 2203 if (UNEXPECTED(EX(fbc) == NULL)) { 2204 zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval); 2205 } 2206 if (OP2_TYPE == IS_CONST && 2207 EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) && 2208 EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) && 2209 EXPECTED(EX(object) == object)) { 2210 CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc)); 2211 } 2212 } 2213 } else { 2214 zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); 2215 } 2216 2217 if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) { 2218 EX(object) = NULL; 2219 } else { 2220 if (!PZVAL_IS_REF(EX(object))) { 2221 Z_ADDREF_P(EX(object)); /* For $this pointer */ 2222 } else { 2223 zval *this_ptr; 2224 ALLOC_ZVAL(this_ptr); 2225 INIT_PZVAL_COPY(this_ptr, EX(object)); 2226 zval_copy_ctor(this_ptr); 2227 EX(object) = this_ptr; 2228 } 2229 } 2230 2231 FREE_OP2(); 2232 FREE_OP1_IF_VAR(); 2233 2234 CHECK_EXCEPTION(); 2235 ZEND_VM_NEXT_OPCODE(); 2236} 2237 2238ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUSED|CV) 2239{ 2240 USE_OPLINE 2241 zval *function_name; 2242 zend_class_entry *ce; 2243 2244 SAVE_OPLINE(); 2245 zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); 2246 2247 if (OP1_TYPE == IS_CONST) { 2248 /* no function found. try a static method in class */ 2249 if (CACHED_PTR(opline->op1.literal->cache_slot)) { 2250 ce = CACHED_PTR(opline->op1.literal->cache_slot); 2251 } else { 2252 ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), opline->op1.literal + 1, opline->extended_value TSRMLS_CC); 2253 if (UNEXPECTED(ce == NULL)) { 2254 CHECK_EXCEPTION(); 2255 ZEND_VM_NEXT_OPCODE(); 2256 } 2257 CACHE_PTR(opline->op1.literal->cache_slot, ce); 2258 } 2259 EX(called_scope) = ce; 2260 } else { 2261 ce = EX_T(opline->op1.var).class_entry; 2262 2263 if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) { 2264 EX(called_scope) = EG(called_scope); 2265 } else { 2266 EX(called_scope) = ce; 2267 } 2268 } 2269 2270 if (OP1_TYPE == IS_CONST && 2271 OP2_TYPE == IS_CONST && 2272 CACHED_PTR(opline->op2.literal->cache_slot)) { 2273 EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot); 2274 } else if (OP1_TYPE != IS_CONST && 2275 OP2_TYPE == IS_CONST && 2276 (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) { 2277 /* do nothing */ 2278 } else if (OP2_TYPE != IS_UNUSED) { 2279 char *function_name_strval = NULL; 2280 int function_name_strlen = 0; 2281 zend_free_op free_op2; 2282 2283 if (OP2_TYPE == IS_CONST) { 2284 function_name_strval = Z_STRVAL_P(opline->op2.zv); 2285 function_name_strlen = Z_STRLEN_P(opline->op2.zv); 2286 } else { 2287 function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); 2288 2289 if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { 2290 zend_error_noreturn(E_ERROR, "Function name must be a string"); 2291 } else { 2292 function_name_strval = Z_STRVAL_P(function_name); 2293 function_name_strlen = Z_STRLEN_P(function_name); 2294 } 2295 } 2296 2297 if (function_name_strval) { 2298 if (ce->get_static_method) { 2299 EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); 2300 } else { 2301 EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((OP2_TYPE == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC); 2302 } 2303 if (UNEXPECTED(EX(fbc) == NULL)) { 2304 zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval); 2305 } 2306 if (OP2_TYPE == IS_CONST && 2307 EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) && 2308 EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) { 2309 if (OP1_TYPE == IS_CONST) { 2310 CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc)); 2311 } else { 2312 CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc)); 2313 } 2314 } 2315 } 2316 if (OP2_TYPE != IS_CONST) { 2317 FREE_OP2(); 2318 } 2319 } else { 2320 if (UNEXPECTED(ce->constructor == NULL)) { 2321 zend_error_noreturn(E_ERROR, "Cannot call constructor"); 2322 } 2323 if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { 2324 zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name); 2325 } 2326 EX(fbc) = ce->constructor; 2327 } 2328 2329 if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) { 2330 EX(object) = NULL; 2331 } else { 2332 if (EG(This) && 2333 Z_OBJ_HT_P(EG(This))->get_class_entry && 2334 !instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) { 2335 /* We are calling method of the other (incompatible) class, 2336 but passing $this. This is done for compatibility with php-4. */ 2337 if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { 2338 zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name); 2339 } else { 2340 /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ 2341 zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name); 2342 } 2343 } 2344 if ((EX(object) = EG(This))) { 2345 Z_ADDREF_P(EX(object)); 2346 EX(called_scope) = Z_OBJCE_P(EX(object)); 2347 } 2348 } 2349 2350 CHECK_EXCEPTION(); 2351 ZEND_VM_NEXT_OPCODE(); 2352} 2353 2354ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) 2355{ 2356 USE_OPLINE 2357 zval *function_name; 2358 zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); 2359 2360 if (OP2_TYPE == IS_CONST) { 2361 function_name = (zval*)(opline->op2.literal+1); 2362 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 2363 EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot); 2364 } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) { 2365 SAVE_OPLINE(); 2366 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv)); 2367 } else { 2368 CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc)); 2369 } 2370 EX(object) = NULL; 2371 /*CHECK_EXCEPTION();*/ 2372 ZEND_VM_NEXT_OPCODE(); 2373 } else { 2374 char *function_name_strval, *lcname; 2375 int function_name_strlen; 2376 zend_free_op free_op2; 2377 2378 SAVE_OPLINE(); 2379 function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); 2380 2381 if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { 2382 function_name_strval = Z_STRVAL_P(function_name); 2383 function_name_strlen = Z_STRLEN_P(function_name); 2384 if (function_name_strval[0] == '\\') { 2385 function_name_strlen -= 1; 2386 lcname = zend_str_tolower_dup(function_name_strval + 1, function_name_strlen); 2387 } else { 2388 lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen); 2389 } 2390 if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) { 2391 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); 2392 } 2393 efree(lcname); 2394 FREE_OP2(); 2395 EX(object) = NULL; 2396 CHECK_EXCEPTION(); 2397 ZEND_VM_NEXT_OPCODE(); 2398 } else if (OP2_TYPE != IS_CONST && OP2_TYPE != IS_TMP_VAR && 2399 EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && 2400 Z_OBJ_HANDLER_P(function_name, get_closure) && 2401 Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { 2402 if (EX(object)) { 2403 Z_ADDREF_P(EX(object)); 2404 } 2405 if (OP2_TYPE == IS_VAR && OP2_FREE && 2406 EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) { 2407 /* Delay closure destruction until its invocation */ 2408 EX(fbc)->common.prototype = (zend_function*)function_name; 2409 } else { 2410 FREE_OP2(); 2411 } 2412 CHECK_EXCEPTION(); 2413 ZEND_VM_NEXT_OPCODE(); 2414 } else if (OP2_TYPE != IS_CONST && 2415 EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && 2416 zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { 2417 zend_class_entry *ce; 2418 zval **method = NULL; 2419 zval **obj = NULL; 2420 2421 zend_hash_index_find(Z_ARRVAL_P(function_name), 0, (void **) &obj); 2422 zend_hash_index_find(Z_ARRVAL_P(function_name), 1, (void **) &method); 2423 2424 if (Z_TYPE_PP(obj) != IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT) { 2425 zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); 2426 } 2427 2428 if (Z_TYPE_PP(method) != IS_STRING) { 2429 zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); 2430 } 2431 2432 if (Z_TYPE_PP(obj) == IS_STRING) { 2433 ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC); 2434 if (UNEXPECTED(ce == NULL)) { 2435 CHECK_EXCEPTION(); 2436 ZEND_VM_NEXT_OPCODE(); 2437 } 2438 EX(called_scope) = ce; 2439 EX(object) = NULL; 2440 2441 if (ce->get_static_method) { 2442 EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC); 2443 } else { 2444 EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); 2445 } 2446 } else { 2447 EX(object) = *obj; 2448 ce = EX(called_scope) = Z_OBJCE_PP(obj); 2449 2450 EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC); 2451 if (UNEXPECTED(EX(fbc) == NULL)) { 2452 zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method)); 2453 } 2454 2455 if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) { 2456 EX(object) = NULL; 2457 } else { 2458 if (!PZVAL_IS_REF(EX(object))) { 2459 Z_ADDREF_P(EX(object)); /* For $this pointer */ 2460 } else { 2461 zval *this_ptr; 2462 ALLOC_ZVAL(this_ptr); 2463 INIT_PZVAL_COPY(this_ptr, EX(object)); 2464 zval_copy_ctor(this_ptr); 2465 EX(object) = this_ptr; 2466 } 2467 } 2468 } 2469 2470 if (UNEXPECTED(EX(fbc) == NULL)) { 2471 zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); 2472 } 2473 FREE_OP2(); 2474 CHECK_EXCEPTION(); 2475 ZEND_VM_NEXT_OPCODE(); 2476 } else { 2477 zend_error_noreturn(E_ERROR, "Function name must be a string"); 2478 } 2479 } 2480} 2481 2482 2483ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST) 2484{ 2485 USE_OPLINE 2486 zend_literal *func_name; 2487 2488 zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); 2489 2490 func_name = opline->op2.literal + 1; 2491 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 2492 EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot); 2493 } else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE) { 2494 func_name++; 2495 if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE)) { 2496 SAVE_OPLINE(); 2497 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv)); 2498 } else { 2499 CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc)); 2500 } 2501 } else { 2502 CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc)); 2503 } 2504 2505 EX(object) = NULL; 2506 ZEND_VM_NEXT_OPCODE(); 2507} 2508 2509ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) 2510{ 2511 zend_bool nested; 2512 zend_op_array *op_array = EX(op_array); 2513 2514 EG(current_execute_data) = EX(prev_execute_data); 2515 EG(opline_ptr) = NULL; 2516 if (!EG(active_symbol_table)) { 2517 zval ***cv = EX_CVs(); 2518 zval ***end = cv + op_array->last_var; 2519 while (cv != end) { 2520 if (*cv) { 2521 zval_ptr_dtor(*cv); 2522 } 2523 cv++; 2524 } 2525 } 2526 2527 if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) { 2528 zval_ptr_dtor((zval**)&op_array->prototype); 2529 } 2530 2531 nested = EX(nested); 2532 2533 zend_vm_stack_free(execute_data TSRMLS_CC); 2534 2535 if (nested) { 2536 execute_data = EG(current_execute_data); 2537 } 2538 if (nested) { 2539 USE_OPLINE 2540 2541 LOAD_REGS(); 2542 LOAD_OPLINE(); 2543 if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) { 2544 2545 EX(function_state).function = (zend_function *) EX(op_array); 2546 EX(function_state).arguments = NULL; 2547 EX(object) = EX(current_object); 2548 2549 EG(opline_ptr) = &EX(opline); 2550 EG(active_op_array) = EX(op_array); 2551 EG(return_value_ptr_ptr) = EX(original_return_value); 2552 destroy_op_array(op_array TSRMLS_CC); 2553 efree(op_array); 2554 if (UNEXPECTED(EG(exception) != NULL)) { 2555 zend_throw_exception_internal(NULL TSRMLS_CC); 2556 HANDLE_EXCEPTION_LEAVE(); 2557 } else if (RETURN_VALUE_USED(opline)) { 2558 if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */ 2559 zval *retval; 2560 2561 ALLOC_ZVAL(retval); 2562 ZVAL_BOOL(retval, 1); 2563 INIT_PZVAL(retval); 2564 EX_T(opline->result.var).var.ptr = retval; 2565 } 2566 } 2567 2568 ZEND_VM_INC_OPCODE(); 2569 ZEND_VM_LEAVE(); 2570 } else { 2571 2572 EG(opline_ptr) = &EX(opline); 2573 EG(active_op_array) = EX(op_array); 2574 EG(return_value_ptr_ptr) = EX(original_return_value); 2575 if (EG(active_symbol_table)) { 2576 if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) { 2577 zend_hash_destroy(EG(active_symbol_table)); 2578 FREE_HASHTABLE(EG(active_symbol_table)); 2579 } else { 2580 /* clean before putting into the cache, since clean 2581 could call dtors, which could use cached hash */ 2582 zend_hash_clean(EG(active_symbol_table)); 2583 *(++EG(symtable_cache_ptr)) = EG(active_symbol_table); 2584 } 2585 } 2586 EG(active_symbol_table) = EX(symbol_table); 2587 2588 EX(function_state).function = (zend_function *) EX(op_array); 2589 EX(function_state).arguments = NULL; 2590 2591 if (EG(This)) { 2592 if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) { 2593 if (IS_CTOR_USED(EX(called_scope))) { 2594 Z_DELREF_P(EG(This)); 2595 } 2596 if (Z_REFCOUNT_P(EG(This)) == 1) { 2597 zend_object_store_ctor_failed(EG(This) TSRMLS_CC); 2598 } 2599 } 2600 zval_ptr_dtor(&EG(This)); 2601 } 2602 EG(This) = EX(current_this); 2603 EG(scope) = EX(current_scope); 2604 EG(called_scope) = EX(current_called_scope); 2605 2606 EX(object) = EX(current_object); 2607 EX(called_scope) = DECODE_CTOR(EX(called_scope)); 2608 2609 zend_vm_stack_clear_multiple(TSRMLS_C); 2610 2611 if (UNEXPECTED(EG(exception) != NULL)) { 2612 zend_throw_exception_internal(NULL TSRMLS_CC); 2613 if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) { 2614 zval_ptr_dtor(&EX_T(opline->result.var).var.ptr); 2615 } 2616 HANDLE_EXCEPTION_LEAVE(); 2617 } 2618 2619 ZEND_VM_INC_OPCODE(); 2620 ZEND_VM_LEAVE(); 2621 } 2622 } 2623 ZEND_VM_RETURN(); 2624} 2625 2626ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) 2627{ 2628 USE_OPLINE 2629 zend_bool should_change_scope = 0; 2630 zend_function *fbc = EX(function_state).function; 2631 2632 SAVE_OPLINE(); 2633 if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) { 2634 if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) { 2635 zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name); 2636 CHECK_EXCEPTION(); 2637 ZEND_VM_NEXT_OPCODE(); /* Never reached */ 2638 } 2639 if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) { 2640 zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", 2641 fbc->common.scope ? fbc->common.scope->name : "", 2642 fbc->common.scope ? "::" : "", 2643 fbc->common.function_name); 2644 } 2645 } 2646 if (fbc->common.scope && 2647 !(fbc->common.fn_flags & ZEND_ACC_STATIC) && 2648 !EX(object)) { 2649 2650 if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { 2651 /* FIXME: output identifiers properly */ 2652 zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name, fbc->common.function_name); 2653 } else { 2654 /* FIXME: output identifiers properly */ 2655 /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ 2656 zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", fbc->common.scope->name, fbc->common.function_name); 2657 } 2658 } 2659 2660 if (fbc->type == ZEND_USER_FUNCTION || fbc->common.scope) { 2661 should_change_scope = 1; 2662 EX(current_this) = EG(This); 2663 EX(current_scope) = EG(scope); 2664 EX(current_called_scope) = EG(called_scope); 2665 EG(This) = EX(object); 2666 EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL; 2667 EG(called_scope) = EX(called_scope); 2668 } 2669 2670 zend_arg_types_stack_3_pop(&EG(arg_types_stack), &EX(called_scope), &EX(current_object), &EX(fbc)); 2671 EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC); 2672 LOAD_OPLINE(); 2673 2674 if (fbc->type == ZEND_INTERNAL_FUNCTION) { 2675 temp_variable *ret = &EX_T(opline->result.var); 2676 2677 MAKE_STD_ZVAL(ret->var.ptr); 2678 ZVAL_NULL(ret->var.ptr); 2679 ret->var.ptr_ptr = &ret->var.ptr; 2680 ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0; 2681 2682 if (fbc->common.arg_info) { 2683 zend_uint i=0; 2684 zval **p = (zval**)EX(function_state).arguments; 2685 ulong arg_count = opline->extended_value; 2686 2687 while (arg_count>0) { 2688 zend_verify_arg_type(fbc, ++i, *(p-arg_count), 0 TSRMLS_CC); 2689 arg_count--; 2690 } 2691 } 2692 2693 if (!zend_execute_internal) { 2694 /* saves one function call if zend_execute_internal is not used */ 2695 fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); 2696 } else { 2697 zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC); 2698 } 2699 2700 if (!RETURN_VALUE_USED(opline)) { 2701 zval_ptr_dtor(&ret->var.ptr); 2702 } 2703 } else if (fbc->type == ZEND_USER_FUNCTION) { 2704 EX(original_return_value) = EG(return_value_ptr_ptr); 2705 EG(active_symbol_table) = NULL; 2706 EG(active_op_array) = &fbc->op_array; 2707 EG(return_value_ptr_ptr) = NULL; 2708 if (RETURN_VALUE_USED(opline)) { 2709 temp_variable *ret = &EX_T(opline->result.var); 2710 2711 ret->var.ptr = NULL; 2712 EG(return_value_ptr_ptr) = &ret->var.ptr; 2713 ret->var.ptr_ptr = &ret->var.ptr; 2714 ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0; 2715 } 2716 2717 if (EXPECTED(zend_execute == execute)) { 2718 if (EXPECTED(EG(exception) == NULL)) { 2719 ZEND_VM_ENTER(); 2720 } 2721 } else { 2722 zend_execute(EG(active_op_array) TSRMLS_CC); 2723 } 2724 2725 EG(opline_ptr) = &EX(opline); 2726 EG(active_op_array) = EX(op_array); 2727 EG(return_value_ptr_ptr) = EX(original_return_value); 2728 if (EG(active_symbol_table)) { 2729 if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) { 2730 zend_hash_destroy(EG(active_symbol_table)); 2731 FREE_HASHTABLE(EG(active_symbol_table)); 2732 } else { 2733 /* clean before putting into the cache, since clean 2734 could call dtors, which could use cached hash */ 2735 zend_hash_clean(EG(active_symbol_table)); 2736 *(++EG(symtable_cache_ptr)) = EG(active_symbol_table); 2737 } 2738 } 2739 EG(active_symbol_table) = EX(symbol_table); 2740 } else { /* ZEND_OVERLOADED_FUNCTION */ 2741 MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr); 2742 ZVAL_NULL(EX_T(opline->result.var).var.ptr); 2743 2744 /* Not sure what should be done here if it's a static method */ 2745 if (EXPECTED(EX(object) != NULL)) { 2746 Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); 2747 } else { 2748 zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); 2749 } 2750 2751 if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { 2752 efree((char*)fbc->common.function_name); 2753 } 2754 efree(fbc); 2755 2756 if (!RETURN_VALUE_USED(opline)) { 2757 zval_ptr_dtor(&EX_T(opline->result.var).var.ptr); 2758 } else { 2759 Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr); 2760 Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1); 2761 EX_T(opline->result.var).var.fcall_returned_reference = 0; 2762 EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; 2763 } 2764 } 2765 2766 EX(function_state).function = (zend_function *) EX(op_array); 2767 EX(function_state).arguments = NULL; 2768 2769 if (should_change_scope) { 2770 if (EG(This)) { 2771 if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) { 2772 if (IS_CTOR_USED(EX(called_scope))) { 2773 Z_DELREF_P(EG(This)); 2774 } 2775 if (Z_REFCOUNT_P(EG(This)) == 1) { 2776 zend_object_store_ctor_failed(EG(This) TSRMLS_CC); 2777 } 2778 } 2779 zval_ptr_dtor(&EG(This)); 2780 } 2781 EG(This) = EX(current_this); 2782 EG(scope) = EX(current_scope); 2783 EG(called_scope) = EX(current_called_scope); 2784 } 2785 2786 EX(object) = EX(current_object); 2787 EX(called_scope) = DECODE_CTOR(EX(called_scope)); 2788 2789 zend_vm_stack_clear_multiple(TSRMLS_C); 2790 2791 if (UNEXPECTED(EG(exception) != NULL)) { 2792 zend_throw_exception_internal(NULL TSRMLS_CC); 2793 if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) { 2794 zval_ptr_dtor(&EX_T(opline->result.var).var.ptr); 2795 } 2796 HANDLE_EXCEPTION(); 2797 } 2798 2799 ZEND_VM_NEXT_OPCODE(); 2800} 2801 2802ZEND_VM_HANDLER(61, ZEND_DO_FCALL_BY_NAME, ANY, ANY) 2803{ 2804 EX(function_state).function = EX(fbc); 2805 ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper); 2806} 2807 2808ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY) 2809{ 2810 USE_OPLINE 2811 zend_free_op free_op1; 2812 zval *fname = GET_OP1_ZVAL_PTR(BP_VAR_R); 2813 2814 zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); 2815 2816 if (CACHED_PTR(opline->op1.literal->cache_slot)) { 2817 EX(function_state).function = CACHED_PTR(opline->op1.literal->cache_slot); 2818 } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(fname), Z_STRLEN_P(fname)+1, Z_HASH_P(fname), (void **) &EX(function_state).function)==FAILURE)) { 2819 SAVE_OPLINE(); 2820 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", fname->value.str.val); 2821 } else { 2822 CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function); 2823 } 2824 EX(object) = NULL; 2825 2826 FREE_OP1(); 2827 2828 ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper); 2829} 2830 2831ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) 2832{ 2833 USE_OPLINE 2834 zval *retval_ptr; 2835 zend_free_op free_op1; 2836 2837 SAVE_OPLINE(); 2838 retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); 2839 2840 if (!EG(return_value_ptr_ptr)) { 2841 if (OP1_TYPE == IS_TMP_VAR) { 2842 FREE_OP1(); 2843 } 2844 } else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */ 2845 if (OP1_TYPE == IS_CONST || 2846 (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) { 2847 zval *ret; 2848 2849 ALLOC_ZVAL(ret); 2850 INIT_PZVAL_COPY(ret, retval_ptr); 2851 zval_copy_ctor(ret); 2852 *EG(return_value_ptr_ptr) = ret; 2853 } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && 2854 retval_ptr == &EG(uninitialized_zval)) { 2855 zval *ret; 2856 2857 ALLOC_INIT_ZVAL(ret); 2858 *EG(return_value_ptr_ptr) = ret; 2859 } else { 2860 *EG(return_value_ptr_ptr) = retval_ptr; 2861 Z_ADDREF_P(retval_ptr); 2862 } 2863 } else { 2864 zval *ret; 2865 2866 ALLOC_ZVAL(ret); 2867 INIT_PZVAL_COPY(ret, retval_ptr); 2868 *EG(return_value_ptr_ptr) = ret; 2869 } 2870 FREE_OP1_IF_VAR(); 2871 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); 2872} 2873 2874ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY) 2875{ 2876 USE_OPLINE 2877 zval *retval_ptr; 2878 zval **retval_ptr_ptr; 2879 zend_free_op free_op1; 2880 2881 SAVE_OPLINE(); 2882 2883 do { 2884 if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { 2885 /* Not supposed to happen, but we'll allow it */ 2886 zend_error(E_NOTICE, "Only variable references should be returned by reference"); 2887 2888 retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); 2889 if (!EG(return_value_ptr_ptr)) { 2890 if (OP1_TYPE == IS_TMP_VAR) { 2891 FREE_OP1(); 2892 } 2893 } else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */ 2894 zval *ret; 2895 2896 ALLOC_ZVAL(ret); 2897 INIT_PZVAL_COPY(ret, retval_ptr); 2898 zval_copy_ctor(ret); 2899 *EG(return_value_ptr_ptr) = ret; 2900 } else { 2901 zval *ret; 2902 2903 ALLOC_ZVAL(ret); 2904 INIT_PZVAL_COPY(ret, retval_ptr); 2905 *EG(return_value_ptr_ptr) = ret; 2906 } 2907 break; 2908 } 2909 2910 retval_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); 2911 2912 if (OP1_TYPE == IS_VAR && UNEXPECTED(retval_ptr_ptr == NULL)) { 2913 zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); 2914 } 2915 2916 if (OP1_TYPE == IS_VAR && !Z_ISREF_PP(retval_ptr_ptr)) { 2917 if (opline->extended_value == ZEND_RETURNS_FUNCTION && 2918 EX_T(opline->op1.var).var.fcall_returned_reference) { 2919 } else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) { 2920 zend_error(E_NOTICE, "Only variable references should be returned by reference"); 2921 if (EG(return_value_ptr_ptr)) { 2922 retval_ptr = *retval_ptr_ptr; 2923 *EG(return_value_ptr_ptr) = retval_ptr; 2924 Z_ADDREF_P(retval_ptr); 2925 } 2926 break; 2927 } 2928 } 2929 2930 if (EG(return_value_ptr_ptr)) { 2931 SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr); 2932 Z_ADDREF_PP(retval_ptr_ptr); 2933 2934 *EG(return_value_ptr_ptr) = *retval_ptr_ptr; 2935 } 2936 } while (0); 2937 2938 FREE_OP1_IF_VAR(); 2939 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); 2940} 2941 2942ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) 2943{ 2944 USE_OPLINE 2945 zval *value; 2946 zval *exception; 2947 zend_free_op free_op1; 2948 2949 SAVE_OPLINE(); 2950 value = GET_OP1_ZVAL_PTR(BP_VAR_R); 2951 2952 if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { 2953 zend_error_noreturn(E_ERROR, "Can only throw objects"); 2954 } 2955 zend_exception_save(TSRMLS_C); 2956 /* Not sure if a complete copy is what we want here */ 2957 ALLOC_ZVAL(exception); 2958 INIT_PZVAL_COPY(exception, value); 2959 if (!IS_OP1_TMP_FREE()) { 2960 zval_copy_ctor(exception); 2961 } 2962 2963 zend_throw_exception_object(exception TSRMLS_CC); 2964 zend_exception_restore(TSRMLS_C); 2965 FREE_OP1_IF_VAR(); 2966 HANDLE_EXCEPTION(); 2967} 2968 2969ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) 2970{ 2971 USE_OPLINE 2972 zend_class_entry *ce, *catch_ce; 2973 zval *exception; 2974 2975 SAVE_OPLINE(); 2976 /* Check whether an exception has been thrown, if not, jump over code */ 2977 zend_exception_restore(TSRMLS_C); 2978 if (EG(exception) == NULL) { 2979 ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]); 2980 ZEND_VM_CONTINUE(); /* CHECK_ME */ 2981 } 2982 if (CACHED_PTR(opline->op1.literal->cache_slot)) { 2983 catch_ce = CACHED_PTR(opline->op1.literal->cache_slot); 2984 } else { 2985 catch_ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), opline->op1.literal + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC); 2986 2987 CACHE_PTR(opline->op1.literal->cache_slot, catch_ce); 2988 } 2989 ce = Z_OBJCE_P(EG(exception)); 2990 2991#ifdef HAVE_DTRACE 2992 if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) { 2993 DTRACE_EXCEPTION_CAUGHT(ce->name); 2994 } 2995#endif /* HAVE_DTRACE */ 2996 2997 if (ce != catch_ce) { 2998 if (!instanceof_function(ce, catch_ce TSRMLS_CC)) { 2999 if (opline->result.num) { 3000 zend_throw_exception_internal(NULL TSRMLS_CC); 3001 HANDLE_EXCEPTION(); 3002 } 3003 ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]); 3004 ZEND_VM_CONTINUE(); /* CHECK_ME */ 3005 } 3006 } 3007 3008 exception = EG(exception); 3009 if (!EG(active_symbol_table)) { 3010 if (EX_CV(opline->op2.var)) { 3011 zval_ptr_dtor(EX_CV(opline->op2.var)); 3012 } 3013 EX_CV(opline->op2.var) = (zval**)EX_CVs() + (EX(op_array)->last_var + opline->op2.var); 3014 *EX_CV(opline->op2.var) = EG(exception); 3015 } else { 3016 zend_compiled_variable *cv = &CV_DEF_OF(opline->op2.var); 3017 zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, 3018 &EG(exception), sizeof(zval *), (void**)&EX_CV(opline->op2.var)); 3019 } 3020 if (UNEXPECTED(EG(exception) != exception)) { 3021 Z_ADDREF_P(EG(exception)); 3022 HANDLE_EXCEPTION(); 3023 } else { 3024 EG(exception) = NULL; 3025 ZEND_VM_NEXT_OPCODE(); 3026 } 3027} 3028 3029ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) 3030{ 3031 USE_OPLINE 3032 3033 SAVE_OPLINE(); 3034 if (opline->extended_value==ZEND_DO_FCALL_BY_NAME 3035 && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) { 3036 zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num); 3037 } 3038 { 3039 zval *valptr; 3040 zval *value; 3041 zend_free_op free_op1; 3042 3043 value = GET_OP1_ZVAL_PTR(BP_VAR_R); 3044 3045 ALLOC_ZVAL(valptr); 3046 INIT_PZVAL_COPY(valptr, value); 3047 if (!IS_OP1_TMP_FREE()) { 3048 zval_copy_ctor(valptr); 3049 } 3050 zend_vm_stack_push(valptr TSRMLS_CC); 3051 FREE_OP1_IF_VAR(); 3052 } 3053 CHECK_EXCEPTION(); 3054 ZEND_VM_NEXT_OPCODE(); 3055} 3056 3057ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY) 3058{ 3059 USE_OPLINE 3060 zval *varptr; 3061 zend_free_op free_op1; 3062 varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); 3063 3064 if (varptr == &EG(uninitialized_zval)) { 3065 ALLOC_ZVAL(varptr); 3066 INIT_ZVAL(*varptr); 3067 Z_SET_REFCOUNT_P(varptr, 0); 3068 } else if (PZVAL_IS_REF(varptr)) { 3069 zval *original_var = varptr; 3070 3071 ALLOC_ZVAL(varptr); 3072 ZVAL_COPY_VALUE(varptr, original_var); 3073 Z_UNSET_ISREF_P(varptr); 3074 Z_SET_REFCOUNT_P(varptr, 0); 3075 zval_copy_ctor(varptr); 3076 } 3077 Z_ADDREF_P(varptr); 3078 zend_vm_stack_push(varptr TSRMLS_CC); 3079 FREE_OP1(); /* for string offsets */ 3080 3081 CHECK_EXCEPTION(); 3082 ZEND_VM_NEXT_OPCODE(); 3083} 3084 3085ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) 3086{ 3087 USE_OPLINE 3088 zend_free_op free_op1; 3089 zval *varptr; 3090 3091 SAVE_OPLINE(); 3092 if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ 3093 if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { 3094 ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); 3095 } 3096 } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) { 3097 ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); 3098 } 3099 3100 if (OP1_TYPE == IS_VAR && 3101 (opline->extended_value & ZEND_ARG_SEND_FUNCTION) && 3102 EX_T(opline->op1.var).var.fcall_returned_reference && 3103 EX_T(opline->op1.var).var.ptr) { 3104 varptr = EX_T(opline->op1.var).var.ptr; 3105 PZVAL_UNLOCK_EX(varptr, &free_op1, 0); 3106 } else { 3107 varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); 3108 } 3109 if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || 3110 EX_T(opline->op1.var).var.fcall_returned_reference) && 3111 varptr != &EG(uninitialized_zval) && 3112 (PZVAL_IS_REF(varptr) || 3113 (Z_REFCOUNT_P(varptr) == 1 && (OP1_TYPE == IS_CV || free_op1.var)))) { 3114 Z_SET_ISREF_P(varptr); 3115 Z_ADDREF_P(varptr); 3116 zend_vm_stack_push(varptr TSRMLS_CC); 3117 } else { 3118 zval *valptr; 3119 3120 if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? 3121 !(opline->extended_value & ZEND_ARG_SEND_SILENT) : 3122 !ARG_MAY_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) { 3123 zend_error(E_STRICT, "Only variables should be passed by reference"); 3124 } 3125 ALLOC_ZVAL(valptr); 3126 INIT_PZVAL_COPY(valptr, varptr); 3127 if (!IS_OP1_TMP_FREE()) { 3128 zval_copy_ctor(valptr); 3129 } 3130 zend_vm_stack_push(valptr TSRMLS_CC); 3131 } 3132 FREE_OP1_IF_VAR(); 3133 CHECK_EXCEPTION(); 3134 ZEND_VM_NEXT_OPCODE(); 3135} 3136 3137ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) 3138{ 3139 USE_OPLINE 3140 zend_free_op free_op1; 3141 zval **varptr_ptr; 3142 zval *varptr; 3143 3144 SAVE_OPLINE(); 3145 varptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); 3146 3147 if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) { 3148 zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); 3149 } 3150 3151 if (OP1_TYPE == IS_VAR && UNEXPECTED(*varptr_ptr == &EG(error_zval))) { 3152 ALLOC_INIT_ZVAL(varptr); 3153 zend_vm_stack_push(varptr TSRMLS_CC); 3154 CHECK_EXCEPTION(); 3155 ZEND_VM_NEXT_OPCODE(); 3156 } 3157 3158 if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) { 3159 ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); 3160 } 3161 3162 SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); 3163 varptr = *varptr_ptr; 3164 Z_ADDREF_P(varptr); 3165 zend_vm_stack_push(varptr TSRMLS_CC); 3166 3167 FREE_OP1_VAR_PTR(); 3168 CHECK_EXCEPTION(); 3169 ZEND_VM_NEXT_OPCODE(); 3170} 3171 3172ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY) 3173{ 3174 USE_OPLINE 3175 3176 if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME) 3177 && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) { 3178 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF); 3179 } 3180 SAVE_OPLINE(); 3181 ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); 3182} 3183 3184ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY) 3185{ 3186 USE_OPLINE 3187 zend_uint arg_num = opline->op1.num; 3188 zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC); 3189 3190 SAVE_OPLINE(); 3191 if (UNEXPECTED(param == NULL)) { 3192 if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC)) { 3193 const char *space; 3194 const char *class_name; 3195 zend_execute_data *ptr; 3196 3197 if (EG(active_op_array)->scope) { 3198 class_name = EG(active_op_array)->scope->name; 3199 space = "::"; 3200 } else { 3201 class_name = space = ""; 3202 } 3203 ptr = EX(prev_execute_data); 3204 3205 if(ptr && ptr->op_array) { 3206 zend_error(E_WARNING, "Missing argument %u for %s%s%s(), called in %s on line %d and defined", opline->op1.num, class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno); 3207 } else { 3208 zend_error(E_WARNING, "Missing argument %u for %s%s%s()", opline->op1.num, class_name, space, get_active_function_name(TSRMLS_C)); 3209 } 3210 } 3211 } else { 3212 zval **var_ptr; 3213 3214 zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC); 3215 var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC); 3216 Z_DELREF_PP(var_ptr); 3217 *var_ptr = *param; 3218 Z_ADDREF_PP(var_ptr); 3219 } 3220 3221 CHECK_EXCEPTION(); 3222 ZEND_VM_NEXT_OPCODE(); 3223} 3224 3225ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) 3226{ 3227 USE_OPLINE 3228 zval *assignment_value; 3229 zend_uint arg_num = opline->op1.num; 3230 zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC); 3231 zval **var_ptr; 3232 3233 SAVE_OPLINE(); 3234 if (param == NULL) { 3235 ALLOC_ZVAL(assignment_value); 3236 *assignment_value = *opline->op2.zv; 3237 if ((Z_TYPE_P(assignment_value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || 3238 Z_TYPE_P(assignment_value)==IS_CONSTANT_ARRAY) { 3239 Z_SET_REFCOUNT_P(assignment_value, 1); 3240 zval_update_constant(&assignment_value, 0 TSRMLS_CC); 3241 } else { 3242 zval_copy_ctor(assignment_value); 3243 } 3244 INIT_PZVAL(assignment_value); 3245 } else { 3246 assignment_value = *param; 3247 Z_ADDREF_P(assignment_value); 3248 } 3249 3250 zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC); 3251 var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC); 3252 Z_DELREF_PP(var_ptr); 3253 *var_ptr = assignment_value; 3254 3255 CHECK_EXCEPTION(); 3256 ZEND_VM_NEXT_OPCODE(); 3257} 3258 3259ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMP|VAR|CV, ANY) 3260{ 3261 USE_OPLINE 3262 zend_free_op free_op1; 3263 zval *retval = &EX_T(opline->result.var).tmp_var; 3264 3265 SAVE_OPLINE(); 3266 /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ 3267 ZVAL_BOOL(retval, i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R))); 3268 FREE_OP1(); 3269 3270 CHECK_EXCEPTION(); 3271 ZEND_VM_NEXT_OPCODE(); 3272} 3273 3274ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST) 3275{ 3276 USE_OPLINE 3277 zend_brk_cont_element *el; 3278 3279 SAVE_OPLINE(); 3280 el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num, 3281 EX(op_array), EX_Ts() TSRMLS_CC); 3282 FREE_OP2(); 3283 ZEND_VM_JMP(EX(op_array)->opcodes + el->brk); 3284} 3285 3286ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST) 3287{ 3288 USE_OPLINE 3289 zend_brk_cont_element *el; 3290 3291 SAVE_OPLINE(); 3292 el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num, 3293 EX(op_array), EX_Ts() TSRMLS_CC); 3294 FREE_OP2(); 3295 ZEND_VM_JMP(EX(op_array)->opcodes + el->cont); 3296} 3297 3298ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST) 3299{ 3300 zend_op *brk_opline; 3301 USE_OPLINE 3302 zend_brk_cont_element *el; 3303 3304 SAVE_OPLINE(); 3305 el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->extended_value, 3306 EX(op_array), EX_Ts() TSRMLS_CC); 3307 3308 brk_opline = EX(op_array)->opcodes + el->brk; 3309 3310 switch (brk_opline->opcode) { 3311 case ZEND_SWITCH_FREE: 3312 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { 3313 zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr); 3314 } 3315 break; 3316 case ZEND_FREE: 3317 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { 3318 zendi_zval_dtor(EX_T(brk_opline->op1.var).tmp_var); 3319 } 3320 break; 3321 } 3322 ZEND_VM_JMP(opline->op1.jmp_addr); 3323} 3324 3325ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) 3326{ 3327 USE_OPLINE 3328 zend_free_op free_op1, free_op2; 3329 3330 SAVE_OPLINE(); 3331 if (OP1_TYPE==IS_VAR) { 3332 PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); 3333 } 3334 is_equal_function(&EX_T(opline->result.var).tmp_var, 3335 GET_OP1_ZVAL_PTR(BP_VAR_R), 3336 GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); 3337 3338 FREE_OP2(); 3339 CHECK_EXCEPTION(); 3340 ZEND_VM_NEXT_OPCODE(); 3341} 3342 3343ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, VAR, ANY) 3344{ 3345 USE_OPLINE 3346 3347 SAVE_OPLINE(); 3348 zval_ptr_dtor(&EX_T(opline->op1.var).var.ptr); 3349 CHECK_EXCEPTION(); 3350 ZEND_VM_NEXT_OPCODE(); 3351} 3352 3353ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY) 3354{ 3355 USE_OPLINE 3356 zval *object_zval; 3357 zend_function *constructor; 3358 3359 SAVE_OPLINE(); 3360 if (UNEXPECTED((EX_T(opline->op1.var).class_entry->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) { 3361 if (EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_INTERFACE) { 3362 zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", EX_T(opline->op1.var).class_entry->name); 3363 } else if ((EX_T(opline->op1.var).class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { 3364 zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", EX_T(opline->op1.var).class_entry->name); 3365 } else { 3366 zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", EX_T(opline->op1.var).class_entry->name); 3367 } 3368 } 3369 ALLOC_ZVAL(object_zval); 3370 object_init_ex(object_zval, EX_T(opline->op1.var).class_entry); 3371 INIT_PZVAL(object_zval); 3372 3373 constructor = Z_OBJ_HT_P(object_zval)->get_constructor(object_zval TSRMLS_CC); 3374 3375 if (constructor == NULL) { 3376 if (RETURN_VALUE_USED(opline)) { 3377 AI_SET_PTR(&EX_T(opline->result.var), object_zval); 3378 } else { 3379 zval_ptr_dtor(&object_zval); 3380 } 3381 ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.opline_num); 3382 } else { 3383 if (RETURN_VALUE_USED(opline)) { 3384 PZVAL_LOCK(object_zval); 3385 AI_SET_PTR(&EX_T(opline->result.var), object_zval); 3386 } 3387 3388 zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), ENCODE_CTOR(EX(called_scope), RETURN_VALUE_USED(opline))); 3389 3390 /* We are not handling overloaded classes right now */ 3391 EX(object) = object_zval; 3392 EX(fbc) = constructor; 3393 EX(called_scope) = EX_T(opline->op1.var).class_entry; 3394 3395 CHECK_EXCEPTION(); 3396 ZEND_VM_NEXT_OPCODE(); 3397 } 3398} 3399 3400ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY) 3401{ 3402 USE_OPLINE 3403 zend_free_op free_op1; 3404 zval *obj; 3405 zend_class_entry *ce; 3406 zend_function *clone; 3407 zend_object_clone_obj_t clone_call; 3408 3409 SAVE_OPLINE(); 3410 obj = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R); 3411 3412 if (OP1_TYPE == IS_CONST || 3413 UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) { 3414 zend_error_noreturn(E_ERROR, "__clone method called on non-object"); 3415 } 3416 3417 ce = Z_OBJCE_P(obj); 3418 clone = ce ? ce->clone : NULL; 3419 clone_call = Z_OBJ_HT_P(obj)->clone_obj; 3420 if (UNEXPECTED(clone_call == NULL)) { 3421 if (ce) { 3422 zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name); 3423 } else { 3424 zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object"); 3425 } 3426 } 3427 3428 if (ce && clone) { 3429 if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) { 3430 /* Ensure that if we're calling a private function, we're allowed to do so. 3431 */ 3432 if (UNEXPECTED(ce != EG(scope))) { 3433 zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : ""); 3434 } 3435 } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) { 3436 /* Ensure that if we're calling a protected function, we're allowed to do so. 3437 */ 3438 if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) { 3439 zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : ""); 3440 } 3441 } 3442 } 3443 3444 if (EXPECTED(EG(exception) == NULL)) { 3445 zval *retval; 3446 3447 ALLOC_ZVAL(retval); 3448 Z_OBJVAL_P(retval) = clone_call(obj TSRMLS_CC); 3449 Z_TYPE_P(retval) = IS_OBJECT; 3450 Z_SET_REFCOUNT_P(retval, 1); 3451 Z_SET_ISREF_P(retval); 3452 if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { 3453 zval_ptr_dtor(&retval); 3454 } else { 3455 AI_SET_PTR(&EX_T(opline->result.var), retval); 3456 } 3457 } 3458 FREE_OP1_IF_VAR(); 3459 CHECK_EXCEPTION(); 3460 ZEND_VM_NEXT_OPCODE(); 3461} 3462 3463ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) 3464{ 3465 USE_OPLINE 3466 3467 SAVE_OPLINE(); 3468 if (OP1_TYPE == IS_UNUSED) { 3469 zend_constant *c; 3470 zval *retval; 3471 3472 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 3473 c = CACHED_PTR(opline->op2.literal->cache_slot); 3474 } else if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) { 3475 if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { 3476 char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv)); 3477 if(!actual) { 3478 actual = Z_STRVAL_P(opline->op2.zv); 3479 } else { 3480 actual++; 3481 } 3482 /* non-qualified constant - allow text substitution */ 3483 zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); 3484 ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1); 3485 CHECK_EXCEPTION(); 3486 ZEND_VM_NEXT_OPCODE(); 3487 } else { 3488 zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv)); 3489 } 3490 } else { 3491 CACHE_PTR(opline->op2.literal->cache_slot, c); 3492 } 3493 retval = &EX_T(opline->result.var).tmp_var; 3494 ZVAL_COPY_VALUE(retval, &c->value); 3495 zval_copy_ctor(retval); 3496 CHECK_EXCEPTION(); 3497 ZEND_VM_NEXT_OPCODE(); 3498 } else { 3499 /* class constant */ 3500 zend_class_entry *ce; 3501 zval **value; 3502 3503 if (OP1_TYPE == IS_CONST) { 3504 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 3505 value = CACHED_PTR(opline->op2.literal->cache_slot); 3506 ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); 3507 zval_copy_ctor(&EX_T(opline->result.var).tmp_var); 3508 CHECK_EXCEPTION(); 3509 ZEND_VM_NEXT_OPCODE(); 3510 } else if (CACHED_PTR(opline->op1.literal->cache_slot)) { 3511 ce = CACHED_PTR(opline->op1.literal->cache_slot); 3512 } else { 3513 ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), opline->op1.literal + 1, opline->extended_value TSRMLS_CC); 3514 if (UNEXPECTED(ce == NULL)) { 3515 CHECK_EXCEPTION(); 3516 ZEND_VM_NEXT_OPCODE(); 3517 } 3518 CACHE_PTR(opline->op1.literal->cache_slot, ce); 3519 } 3520 } else { 3521 ce = EX_T(opline->op1.var).class_entry; 3522 if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) { 3523 ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); 3524 zval_copy_ctor(&EX_T(opline->result.var).tmp_var); 3525 CHECK_EXCEPTION(); 3526 ZEND_VM_NEXT_OPCODE(); 3527 } 3528 } 3529 3530 if (EXPECTED(zend_hash_quick_find(&ce->constants_table, Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv)+1, Z_HASH_P(opline->op2.zv), (void **) &value) == SUCCESS)) { 3531 if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY || 3532 (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { 3533 zend_class_entry *old_scope = EG(scope); 3534 3535 EG(scope) = ce; 3536 zval_update_constant(value, (void *) 1 TSRMLS_CC); 3537 EG(scope) = old_scope; 3538 } 3539 if (OP1_TYPE == IS_CONST) { 3540 CACHE_PTR(opline->op2.literal->cache_slot, value); 3541 } else { 3542 CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, value); 3543 } 3544 ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); 3545 zval_copy_ctor(&EX_T(opline->result.var).tmp_var); 3546 } else { 3547 zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv)); 3548 } 3549 3550 CHECK_EXCEPTION(); 3551 ZEND_VM_NEXT_OPCODE(); 3552 } 3553} 3554 3555ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUSED|CV) 3556{ 3557 USE_OPLINE 3558 zend_free_op free_op1; 3559 zval *expr_ptr; 3560 3561 SAVE_OPLINE(); 3562 if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && opline->extended_value) { 3563 zval **expr_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); 3564 3565 if (OP1_TYPE == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) { 3566 zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); 3567 } 3568 SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr); 3569 expr_ptr = *expr_ptr_ptr; 3570 Z_ADDREF_P(expr_ptr); 3571 } else { 3572 expr_ptr=GET_OP1_ZVAL_PTR(BP_VAR_R); 3573 if (IS_OP1_TMP_FREE()) { /* temporary variable */ 3574 zval *new_expr; 3575 3576 ALLOC_ZVAL(new_expr); 3577 INIT_PZVAL_COPY(new_expr, expr_ptr); 3578 expr_ptr = new_expr; 3579 } else if (OP1_TYPE == IS_CONST || PZVAL_IS_REF(expr_ptr)) { 3580 zval *new_expr; 3581 3582 ALLOC_ZVAL(new_expr); 3583 INIT_PZVAL_COPY(new_expr, expr_ptr); 3584 expr_ptr = new_expr; 3585 zendi_zval_copy_ctor(*expr_ptr); 3586 } else { 3587 Z_ADDREF_P(expr_ptr); 3588 } 3589 } 3590 3591 if (OP2_TYPE != IS_UNUSED) { 3592 zend_free_op free_op2; 3593 zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R); 3594 ulong hval; 3595 3596 switch (Z_TYPE_P(offset)) { 3597 case IS_DOUBLE: 3598 hval = zend_dval_to_lval(Z_DVAL_P(offset)); 3599 ZEND_VM_C_GOTO(num_index); 3600 case IS_LONG: 3601 case IS_BOOL: 3602 hval = Z_LVAL_P(offset); 3603ZEND_VM_C_LABEL(num_index): 3604 zend_hash_index_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), hval, &expr_ptr, sizeof(zval *), NULL); 3605 break; 3606 case IS_STRING: 3607 if (OP2_TYPE == IS_CONST) { 3608 hval = Z_HASH_P(offset); 3609 } else { 3610 ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index)); 3611 if (IS_INTERNED(Z_STRVAL_P(offset))) { 3612 hval = INTERNED_HASH(Z_STRVAL_P(offset)); 3613 } else { 3614 hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); 3615 } 3616 } 3617 zend_hash_quick_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL); 3618 break; 3619 case IS_NULL: 3620 zend_hash_update(Z_ARRVAL(EX_T(opline->result.var).tmp_var), "", sizeof(""), &expr_ptr, sizeof(zval *), NULL); 3621 break; 3622 default: 3623 zend_error(E_WARNING, "Illegal offset type"); 3624 zval_ptr_dtor(&expr_ptr); 3625 /* do nothing */ 3626 break; 3627 } 3628 FREE_OP2(); 3629 } else { 3630 zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); 3631 } 3632 if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && opline->extended_value) { 3633 FREE_OP1_VAR_PTR(); 3634 } else { 3635 FREE_OP1_IF_VAR(); 3636 } 3637 CHECK_EXCEPTION(); 3638 ZEND_VM_NEXT_OPCODE(); 3639} 3640 3641ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV) 3642{ 3643 USE_OPLINE 3644 3645 array_init(&EX_T(opline->result.var).tmp_var); 3646 if (OP1_TYPE == IS_UNUSED) { 3647 ZEND_VM_NEXT_OPCODE(); 3648#if !defined(ZEND_VM_SPEC) || OP1_TYPE != IS_UNUSED 3649 } else { 3650 ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ADD_ARRAY_ELEMENT); 3651#endif 3652 } 3653} 3654 3655ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY) 3656{ 3657 USE_OPLINE 3658 zend_free_op free_op1; 3659 zval *expr; 3660 zval *result = &EX_T(opline->result.var).tmp_var; 3661 3662 SAVE_OPLINE(); 3663 expr = GET_OP1_ZVAL_PTR(BP_VAR_R); 3664 3665 if (opline->extended_value != IS_STRING) { 3666 ZVAL_COPY_VALUE(result, expr); 3667 if (!IS_OP1_TMP_FREE()) { 3668 zendi_zval_copy_ctor(*result); 3669 } 3670 } 3671 switch (opline->extended_value) { 3672 case IS_NULL: 3673 convert_to_null(result); 3674 break; 3675 case IS_BOOL: 3676 convert_to_boolean(result); 3677 break; 3678 case IS_LONG: 3679 convert_to_long(result); 3680 break; 3681 case IS_DOUBLE: 3682 convert_to_double(result); 3683 break; 3684 case IS_STRING: { 3685 zval var_copy; 3686 int use_copy; 3687 3688 zend_make_printable_zval(expr, &var_copy, &use_copy); 3689 if (use_copy) { 3690 ZVAL_COPY_VALUE(result, &var_copy); 3691 if (IS_OP1_TMP_FREE()) { 3692 FREE_OP1(); 3693 } 3694 } else { 3695 ZVAL_COPY_VALUE(result, expr); 3696 if (!IS_OP1_TMP_FREE()) { 3697 zendi_zval_copy_ctor(*result); 3698 } 3699 } 3700 break; 3701 } 3702 case IS_ARRAY: 3703 convert_to_array(result); 3704 break; 3705 case IS_OBJECT: 3706 convert_to_object(result); 3707 break; 3708 } 3709 FREE_OP1_IF_VAR(); 3710 CHECK_EXCEPTION(); 3711 ZEND_VM_NEXT_OPCODE(); 3712} 3713 3714ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY) 3715{ 3716 USE_OPLINE 3717 zend_op_array *new_op_array=NULL; 3718 zend_free_op free_op1; 3719 zval *inc_filename; 3720 zval *tmp_inc_filename = NULL; 3721 zend_bool failure_retval=0; 3722 3723 SAVE_OPLINE(); 3724 inc_filename = GET_OP1_ZVAL_PTR(BP_VAR_R); 3725 3726 if (inc_filename->type!=IS_STRING) { 3727 MAKE_STD_ZVAL(tmp_inc_filename); 3728 ZVAL_COPY_VALUE(tmp_inc_filename, inc_filename); 3729 zval_copy_ctor(tmp_inc_filename); 3730 convert_to_string(tmp_inc_filename); 3731 inc_filename = tmp_inc_filename; 3732 } 3733 3734 if (opline->extended_value != ZEND_EVAL && strlen(Z_STRVAL_P(inc_filename)) != Z_STRLEN_P(inc_filename)) { 3735 if (opline->extended_value == ZEND_INCLUDE_ONCE || opline->extended_value == ZEND_INCLUDE) { 3736 zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC); 3737 } else { 3738 zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC); 3739 } 3740 } else { 3741 switch (opline->extended_value) { 3742 case ZEND_INCLUDE_ONCE: 3743 case ZEND_REQUIRE_ONCE: { 3744 zend_file_handle file_handle; 3745 char *resolved_path; 3746 3747 resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); 3748 if (resolved_path) { 3749 failure_retval = zend_hash_exists(&EG(included_files), resolved_path, strlen(resolved_path)+1); 3750 } else { 3751 resolved_path = Z_STRVAL_P(inc_filename); 3752 } 3753 3754 if (failure_retval) { 3755 /* do nothing, file already included */ 3756 } else if (SUCCESS == zend_stream_open(resolved_path, &file_handle TSRMLS_CC)) { 3757 3758 if (!file_handle.opened_path) { 3759 file_handle.opened_path = estrdup(resolved_path); 3760 } 3761 3762 if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) { 3763 new_op_array = zend_compile_file(&file_handle, (opline->extended_value==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); 3764 zend_destroy_file_handle(&file_handle TSRMLS_CC); 3765 } else { 3766 zend_file_handle_dtor(&file_handle TSRMLS_CC); 3767 failure_retval=1; 3768 } 3769 } else { 3770 if (opline->extended_value == ZEND_INCLUDE_ONCE) { 3771 zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC); 3772 } else { 3773 zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC); 3774 } 3775 } 3776 if (resolved_path != Z_STRVAL_P(inc_filename)) { 3777 efree(resolved_path); 3778 } 3779 } 3780 break; 3781 case ZEND_INCLUDE: 3782 case ZEND_REQUIRE: 3783 new_op_array = compile_filename(opline->extended_value, inc_filename TSRMLS_CC); 3784 break; 3785 case ZEND_EVAL: { 3786 char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC); 3787 3788 new_op_array = zend_compile_string(inc_filename, eval_desc TSRMLS_CC); 3789 efree(eval_desc); 3790 } 3791 break; 3792 EMPTY_SWITCH_DEFAULT_CASE() 3793 } 3794 } 3795 if (tmp_inc_filename) { 3796 zval_ptr_dtor(&tmp_inc_filename); 3797 } 3798 FREE_OP1(); 3799 if (UNEXPECTED(EG(exception) != NULL)) { 3800 HANDLE_EXCEPTION(); 3801 } else if (EXPECTED(new_op_array != NULL)) { 3802 EX(original_return_value) = EG(return_value_ptr_ptr); 3803 EG(active_op_array) = new_op_array; 3804 if (RETURN_VALUE_USED(opline)) { 3805 EX_T(opline->result.var).var.ptr = NULL; 3806 EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; 3807 EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr; 3808 } else { 3809 EG(return_value_ptr_ptr) = NULL; 3810 } 3811 3812 EX(current_object) = EX(object); 3813 3814 EX(function_state).function = (zend_function *) new_op_array; 3815 EX(object) = NULL; 3816 3817 if (!EG(active_symbol_table)) { 3818 zend_rebuild_symbol_table(TSRMLS_C); 3819 } 3820 3821 if (EXPECTED(zend_execute == execute)) { 3822 ZEND_VM_ENTER(); 3823 } else { 3824 zend_execute(new_op_array TSRMLS_CC); 3825 } 3826 3827 EX(function_state).function = (zend_function *) EX(op_array); 3828 EX(object) = EX(current_object); 3829 3830 EG(opline_ptr) = &EX(opline); 3831 EG(active_op_array) = EX(op_array); 3832 EG(return_value_ptr_ptr) = EX(original_return_value); 3833 destroy_op_array(new_op_array TSRMLS_CC); 3834 efree(new_op_array); 3835 if (UNEXPECTED(EG(exception) != NULL)) { 3836 zend_throw_exception_internal(NULL TSRMLS_CC); 3837 HANDLE_EXCEPTION(); 3838 } else if (RETURN_VALUE_USED(opline)) { 3839 if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */ 3840 zval *retval; 3841 3842 ALLOC_ZVAL(retval); 3843 ZVAL_BOOL(retval, 1); 3844 INIT_PZVAL(retval); 3845 EX_T(opline->result.var).var.ptr = retval; 3846 } 3847 } 3848 3849 } else if (RETURN_VALUE_USED(opline)) { 3850 zval *retval; 3851 3852 ALLOC_ZVAL(retval); 3853 ZVAL_BOOL(retval, failure_retval); 3854 INIT_PZVAL(retval); 3855 AI_SET_PTR(&EX_T(opline->result.var), retval); 3856 } 3857 ZEND_VM_NEXT_OPCODE(); 3858} 3859 3860ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) 3861{ 3862 USE_OPLINE 3863 zval tmp, *varname; 3864 HashTable *target_symbol_table; 3865 zend_free_op free_op1; 3866 3867 SAVE_OPLINE(); 3868 if (OP1_TYPE == IS_CV && 3869 OP2_TYPE == IS_UNUSED && 3870 (opline->extended_value & ZEND_QUICK_SET)) { 3871 if (EG(active_symbol_table)) { 3872 zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.var); 3873 3874 zend_delete_variable(EX(prev_execute_data), EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value TSRMLS_CC); 3875 EX_CV(opline->op1.var) = NULL; 3876 } else if (EX_CV(opline->op1.var)) { 3877 zval_ptr_dtor(EX_CV(opline->op1.var)); 3878 EX_CV(opline->op1.var) = NULL; 3879 } 3880 CHECK_EXCEPTION(); 3881 ZEND_VM_NEXT_OPCODE(); 3882 } 3883 3884 varname = GET_OP1_ZVAL_PTR(BP_VAR_R); 3885 3886 if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { 3887 ZVAL_COPY_VALUE(&tmp, varname); 3888 zval_copy_ctor(&tmp); 3889 convert_to_string(&tmp); 3890 varname = &tmp; 3891 } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { 3892 Z_ADDREF_P(varname); 3893 } 3894 3895 if (OP2_TYPE != IS_UNUSED) { 3896 zend_class_entry *ce; 3897 3898 if (OP2_TYPE == IS_CONST) { 3899 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 3900 ce = CACHED_PTR(opline->op2.literal->cache_slot); 3901 } else { 3902 ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC); 3903 if (UNEXPECTED(ce == NULL)) { 3904 if (OP1_TYPE != IS_CONST && varname == &tmp) { 3905 zval_dtor(&tmp); 3906 } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { 3907 zval_ptr_dtor(&varname); 3908 } 3909 FREE_OP1(); 3910 CHECK_EXCEPTION(); 3911 ZEND_VM_NEXT_OPCODE(); 3912 } 3913 CACHE_PTR(opline->op2.literal->cache_slot, ce); 3914 } 3915 } else { 3916 ce = EX_T(opline->op2.var).class_entry; 3917 } 3918 zend_std_unset_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), ((OP1_TYPE == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); 3919 } else { 3920 ulong hash_value = zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1); 3921 3922 target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); 3923 zend_delete_variable(EXECUTE_DATA, target_symbol_table, varname->value.str.val, varname->value.str.len+1, hash_value TSRMLS_CC); 3924 } 3925 3926 if (OP1_TYPE != IS_CONST && varname == &tmp) { 3927 zval_dtor(&tmp); 3928 } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { 3929 zval_ptr_dtor(&varname); 3930 } 3931 FREE_OP1(); 3932 CHECK_EXCEPTION(); 3933 ZEND_VM_NEXT_OPCODE(); 3934} 3935 3936ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 3937{ 3938 USE_OPLINE 3939 zend_free_op free_op1, free_op2; 3940 zval **container; 3941 zval *offset; 3942 ulong hval; 3943 3944 SAVE_OPLINE(); 3945 container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET); 3946 if (OP1_TYPE == IS_CV && container != &EG(uninitialized_zval_ptr)) { 3947 SEPARATE_ZVAL_IF_NOT_REF(container); 3948 } 3949 offset = GET_OP2_ZVAL_PTR(BP_VAR_R); 3950 3951 if (OP1_TYPE != IS_VAR || container) { 3952 switch (Z_TYPE_PP(container)) { 3953 case IS_ARRAY: { 3954 HashTable *ht = Z_ARRVAL_PP(container); 3955 3956 switch (Z_TYPE_P(offset)) { 3957 case IS_DOUBLE: 3958 hval = zend_dval_to_lval(Z_DVAL_P(offset)); 3959 zend_hash_index_del(ht, hval); 3960 break; 3961 case IS_RESOURCE: 3962 case IS_BOOL: 3963 case IS_LONG: 3964 hval = Z_LVAL_P(offset); 3965 zend_hash_index_del(ht, hval); 3966 break; 3967 case IS_STRING: 3968 if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) { 3969 Z_ADDREF_P(offset); 3970 } 3971 if (OP2_TYPE == IS_CONST) { 3972 hval = Z_HASH_P(offset); 3973 } else { 3974 ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_dim)); 3975 if (IS_INTERNED(Z_STRVAL_P(offset))) { 3976 hval = INTERNED_HASH(Z_STRVAL_P(offset)); 3977 } else { 3978 hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); 3979 } 3980 } 3981 if (ht == &EG(symbol_table)) { 3982 zend_delete_global_variable_ex(offset->value.str.val, offset->value.str.len, hval TSRMLS_CC); 3983 } else { 3984 zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval); 3985 } 3986 if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) { 3987 zval_ptr_dtor(&offset); 3988 } 3989 break; 3990ZEND_VM_C_LABEL(num_index_dim): 3991 zend_hash_index_del(ht, hval); 3992 if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) { 3993 zval_ptr_dtor(&offset); 3994 } 3995 break; 3996 case IS_NULL: 3997 zend_hash_del(ht, "", sizeof("")); 3998 break; 3999 default: 4000 zend_error(E_WARNING, "Illegal offset type in unset"); 4001 break; 4002 } 4003 FREE_OP2(); 4004 break; 4005 } 4006 case IS_OBJECT: 4007 if (UNEXPECTED(Z_OBJ_HT_P(*container)->unset_dimension == NULL)) { 4008 zend_error_noreturn(E_ERROR, "Cannot use object as array"); 4009 } 4010 if (IS_OP2_TMP_FREE()) { 4011 MAKE_REAL_ZVAL_PTR(offset); 4012 } 4013 Z_OBJ_HT_P(*container)->unset_dimension(*container, offset TSRMLS_CC); 4014 if (IS_OP2_TMP_FREE()) { 4015 zval_ptr_dtor(&offset); 4016 } else { 4017 FREE_OP2(); 4018 } 4019 break; 4020 case IS_STRING: 4021 zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); 4022 ZEND_VM_CONTINUE(); /* bailed out before */ 4023 default: 4024 FREE_OP2(); 4025 break; 4026 } 4027 } else { 4028 FREE_OP2(); 4029 } 4030 FREE_OP1_VAR_PTR(); 4031 4032 CHECK_EXCEPTION(); 4033 ZEND_VM_NEXT_OPCODE(); 4034} 4035 4036ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 4037{ 4038 USE_OPLINE 4039 zend_free_op free_op1, free_op2; 4040 zval **container; 4041 zval *offset; 4042 4043 SAVE_OPLINE(); 4044 container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET); 4045 offset = GET_OP2_ZVAL_PTR(BP_VAR_R); 4046 4047 if (OP1_TYPE != IS_VAR || container) { 4048 if (OP1_TYPE == IS_CV && container != &EG(uninitialized_zval_ptr)) { 4049 SEPARATE_ZVAL_IF_NOT_REF(container); 4050 } 4051 if (Z_TYPE_PP(container) == IS_OBJECT) { 4052 if (IS_OP2_TMP_FREE()) { 4053 MAKE_REAL_ZVAL_PTR(offset); 4054 } 4055 if (Z_OBJ_HT_P(*container)->unset_property) { 4056 Z_OBJ_HT_P(*container)->unset_property(*container, offset, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 4057 } else { 4058 zend_error(E_NOTICE, "Trying to unset property of non-object"); 4059 } 4060 if (IS_OP2_TMP_FREE()) { 4061 zval_ptr_dtor(&offset); 4062 } else { 4063 FREE_OP2(); 4064 } 4065 } else { 4066 FREE_OP2(); 4067 } 4068 } else { 4069 FREE_OP2(); 4070 } 4071 FREE_OP1_VAR_PTR(); 4072 4073 CHECK_EXCEPTION(); 4074 ZEND_VM_NEXT_OPCODE(); 4075} 4076 4077ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) 4078{ 4079 USE_OPLINE 4080 zend_free_op free_op1; 4081 zval *array_ptr, **array_ptr_ptr; 4082 HashTable *fe_ht; 4083 zend_object_iterator *iter = NULL; 4084 zend_class_entry *ce = NULL; 4085 zend_bool is_empty = 0; 4086 4087 SAVE_OPLINE(); 4088 4089 if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && 4090 (opline->extended_value & ZEND_FE_RESET_VARIABLE)) { 4091 array_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R); 4092 if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) { 4093 MAKE_STD_ZVAL(array_ptr); 4094 ZVAL_NULL(array_ptr); 4095 } else if (Z_TYPE_PP(array_ptr_ptr) == IS_OBJECT) { 4096 if(Z_OBJ_HT_PP(array_ptr_ptr)->get_class_entry == NULL) { 4097 zend_error(E_WARNING, "foreach() cannot iterate over objects without PHP class"); 4098 ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); 4099 } 4100 4101 ce = Z_OBJCE_PP(array_ptr_ptr); 4102 if (!ce || ce->get_iterator == NULL) { 4103 SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr); 4104 Z_ADDREF_PP(array_ptr_ptr); 4105 } 4106 array_ptr = *array_ptr_ptr; 4107 } else { 4108 if (Z_TYPE_PP(array_ptr_ptr) == IS_ARRAY) { 4109 SEPARATE_ZVAL_IF_NOT_REF(array_ptr_ptr); 4110 if (opline->extended_value & ZEND_FE_FETCH_BYREF) { 4111 Z_SET_ISREF_PP(array_ptr_ptr); 4112 } 4113 } 4114 array_ptr = *array_ptr_ptr; 4115 Z_ADDREF_P(array_ptr); 4116 } 4117 } else { 4118 array_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); 4119 if (IS_OP1_TMP_FREE()) { /* IS_TMP_VAR */ 4120 zval *tmp; 4121 4122 ALLOC_ZVAL(tmp); 4123 INIT_PZVAL_COPY(tmp, array_ptr); 4124 array_ptr = tmp; 4125 if (Z_TYPE_P(array_ptr) == IS_OBJECT) { 4126 ce = Z_OBJCE_P(array_ptr); 4127 if (ce && ce->get_iterator) { 4128 Z_DELREF_P(array_ptr); 4129 } 4130 } 4131 } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { 4132 ce = Z_OBJCE_P(array_ptr); 4133 if (!ce || !ce->get_iterator) { 4134 Z_ADDREF_P(array_ptr); 4135 } 4136 } else if (OP1_TYPE == IS_CONST || 4137 ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && 4138 !Z_ISREF_P(array_ptr) && 4139 Z_REFCOUNT_P(array_ptr) > 1)) { 4140 zval *tmp; 4141 4142 ALLOC_ZVAL(tmp); 4143 INIT_PZVAL_COPY(tmp, array_ptr); 4144 zval_copy_ctor(tmp); 4145 array_ptr = tmp; 4146 } else { 4147 Z_ADDREF_P(array_ptr); 4148 } 4149 } 4150 4151 if (ce && ce->get_iterator) { 4152 iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); 4153 4154 if (iter && EXPECTED(EG(exception) == NULL)) { 4155 array_ptr = zend_iterator_wrap(iter TSRMLS_CC); 4156 } else { 4157 FREE_OP1_IF_VAR(); 4158 if (!EG(exception)) { 4159 zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); 4160 } 4161 zend_throw_exception_internal(NULL TSRMLS_CC); 4162 HANDLE_EXCEPTION(); 4163 } 4164 } 4165 4166 EX_T(opline->result.var).fe.ptr = array_ptr; 4167 4168 if (iter) { 4169 iter->index = 0; 4170 if (iter->funcs->rewind) { 4171 iter->funcs->rewind(iter TSRMLS_CC); 4172 if (UNEXPECTED(EG(exception) != NULL)) { 4173 zval_ptr_dtor(&array_ptr); 4174 FREE_OP1_IF_VAR(); 4175 HANDLE_EXCEPTION(); 4176 } 4177 } 4178 is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; 4179 if (UNEXPECTED(EG(exception) != NULL)) { 4180 zval_ptr_dtor(&array_ptr); 4181 FREE_OP1_IF_VAR(); 4182 HANDLE_EXCEPTION(); 4183 } 4184 iter->index = -1; /* will be set to 0 before using next handler */ 4185 } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { 4186 zend_hash_internal_pointer_reset(fe_ht); 4187 if (ce) { 4188 zend_object *zobj = zend_objects_get_address(array_ptr TSRMLS_CC); 4189 while (zend_hash_has_more_elements(fe_ht) == SUCCESS) { 4190 char *str_key; 4191 uint str_key_len; 4192 ulong int_key; 4193 zend_uchar key_type; 4194 4195 key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL); 4196 if (key_type != HASH_KEY_NON_EXISTANT && 4197 (key_type == HASH_KEY_IS_LONG || 4198 zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) { 4199 break; 4200 } 4201 zend_hash_move_forward(fe_ht); 4202 } 4203 } 4204 is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS; 4205 zend_hash_get_pointer(fe_ht, &EX_T(opline->result.var).fe.fe_pos); 4206 } else { 4207 zend_error(E_WARNING, "Invalid argument supplied for foreach()"); 4208 is_empty = 1; 4209 } 4210 4211 FREE_OP1_IF_VAR(); 4212 if (is_empty) { 4213 ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); 4214 } else { 4215 CHECK_EXCEPTION(); 4216 ZEND_VM_NEXT_OPCODE(); 4217 } 4218} 4219 4220ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) 4221{ 4222 USE_OPLINE 4223 zend_free_op free_op1; 4224 zval *array = EX_T(opline->op1.var).fe.ptr; 4225 zval **value; 4226 char *str_key; 4227 uint str_key_len; 4228 ulong int_key; 4229 HashTable *fe_ht; 4230 zend_object_iterator *iter = NULL; 4231 int key_type = 0; 4232 zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY); 4233 4234 SAVE_OPLINE(); 4235 4236 switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) { 4237 default: 4238 case ZEND_ITER_INVALID: 4239 zend_error(E_WARNING, "Invalid argument supplied for foreach()"); 4240 ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); 4241 4242 case ZEND_ITER_PLAIN_OBJECT: { 4243 const char *class_name, *prop_name; 4244 zend_object *zobj = zend_objects_get_address(array TSRMLS_CC); 4245 4246 fe_ht = Z_OBJPROP_P(array); 4247 zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos); 4248 do { 4249 if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) { 4250 /* reached end of iteration */ 4251 ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); 4252 } 4253 key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL); 4254 4255 zend_hash_move_forward(fe_ht); 4256 } while (key_type == HASH_KEY_NON_EXISTANT || 4257 (key_type != HASH_KEY_IS_LONG && 4258 zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) != SUCCESS)); 4259 zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos); 4260 if (use_key && key_type != HASH_KEY_IS_LONG) { 4261 zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name); 4262 str_key_len = strlen(prop_name); 4263 str_key = estrndup(prop_name, str_key_len); 4264 str_key_len++; 4265 } 4266 break; 4267 } 4268 4269 case ZEND_ITER_PLAIN_ARRAY: 4270 fe_ht = Z_ARRVAL_P(array); 4271 zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos); 4272 if (zend_hash_get_current_data(fe_ht, (void **) &value)==FAILURE) { 4273 /* reached end of iteration */ 4274 ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); 4275 } 4276 if (use_key) { 4277 key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL); 4278 } 4279 zend_hash_move_forward(fe_ht); 4280 zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos); 4281 break; 4282 4283 case ZEND_ITER_OBJECT: 4284 /* !iter happens from exception */ 4285 if (iter && ++iter->index > 0) { 4286 /* This could cause an endless loop if index becomes zero again. 4287 * In case that ever happens we need an additional flag. */ 4288 iter->funcs->move_forward(iter TSRMLS_CC); 4289 if (UNEXPECTED(EG(exception) != NULL)) { 4290 zval_ptr_dtor(&array); 4291 HANDLE_EXCEPTION(); 4292 } 4293 } 4294 /* If index is zero we come from FE_RESET and checked valid() already. */ 4295 if (!iter || (iter->index > 0 && iter->funcs->valid(iter TSRMLS_CC) == FAILURE)) { 4296 /* reached end of iteration */ 4297 if (UNEXPECTED(EG(exception) != NULL)) { 4298 zval_ptr_dtor(&array); 4299 HANDLE_EXCEPTION(); 4300 } 4301 ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); 4302 } 4303 iter->funcs->get_current_data(iter, &value TSRMLS_CC); 4304 if (UNEXPECTED(EG(exception) != NULL)) { 4305 zval_ptr_dtor(&array); 4306 HANDLE_EXCEPTION(); 4307 } 4308 if (!value) { 4309 /* failure in get_current_data */ 4310 ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); 4311 } 4312 if (use_key) { 4313 if (iter->funcs->get_current_key) { 4314 key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC); 4315 if (UNEXPECTED(EG(exception) != NULL)) { 4316 zval_ptr_dtor(&array); 4317 HANDLE_EXCEPTION(); 4318 } 4319 } else { 4320 key_type = HASH_KEY_IS_LONG; 4321 int_key = iter->index; 4322 } 4323 } 4324 break; 4325 } 4326 4327 if (opline->extended_value & ZEND_FE_FETCH_BYREF) { 4328 SEPARATE_ZVAL_IF_NOT_REF(value); 4329 Z_SET_ISREF_PP(value); 4330 EX_T(opline->result.var).var.ptr_ptr = value; 4331 Z_ADDREF_PP(value); 4332 } else { 4333 PZVAL_LOCK(*value); 4334 AI_SET_PTR(&EX_T(opline->result.var), *value); 4335 } 4336 4337 if (use_key) { 4338 zval *key = &EX_T((opline+1)->result.var).tmp_var; 4339 4340 switch (key_type) { 4341 case HASH_KEY_IS_STRING: 4342 Z_STRVAL_P(key) = (char*)str_key; 4343 Z_STRLEN_P(key) = str_key_len-1; 4344 Z_TYPE_P(key) = IS_STRING; 4345 break; 4346 case HASH_KEY_IS_LONG: 4347 Z_LVAL_P(key) = int_key; 4348 Z_TYPE_P(key) = IS_LONG; 4349 break; 4350 default: 4351 case HASH_KEY_NON_EXISTANT: 4352 ZVAL_NULL(key); 4353 break; 4354 } 4355 } 4356 4357 CHECK_EXCEPTION(); 4358 ZEND_VM_INC_OPCODE(); 4359 ZEND_VM_NEXT_OPCODE(); 4360} 4361 4362ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) 4363{ 4364 USE_OPLINE 4365 zval **value; 4366 zend_bool isset = 1; 4367 4368 SAVE_OPLINE(); 4369 if (OP1_TYPE == IS_CV && 4370 OP2_TYPE == IS_UNUSED && 4371 (opline->extended_value & ZEND_QUICK_SET)) { 4372 if (EX_CV(opline->op1.var)) { 4373 value = EX_CV(opline->op1.var); 4374 } else if (EG(active_symbol_table)) { 4375 zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.var); 4376 4377 if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) { 4378 isset = 0; 4379 } 4380 } else { 4381 isset = 0; 4382 } 4383 } else { 4384 HashTable *target_symbol_table; 4385 zend_free_op free_op1; 4386 zval tmp, *varname = GET_OP1_ZVAL_PTR(BP_VAR_IS); 4387 4388 if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { 4389 ZVAL_COPY_VALUE(&tmp, varname); 4390 zval_copy_ctor(&tmp); 4391 convert_to_string(&tmp); 4392 varname = &tmp; 4393 } 4394 4395 if (OP2_TYPE != IS_UNUSED) { 4396 zend_class_entry *ce; 4397 4398 if (OP2_TYPE == IS_CONST) { 4399 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 4400 ce = CACHED_PTR(opline->op2.literal->cache_slot); 4401 } else { 4402 ce = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal + 1, 0 TSRMLS_CC); 4403 if (UNEXPECTED(ce == NULL)) { 4404 CHECK_EXCEPTION(); 4405 ZEND_VM_NEXT_OPCODE(); 4406 } 4407 CACHE_PTR(opline->op2.literal->cache_slot, ce); 4408 } 4409 } else { 4410 ce = EX_T(opline->op2.var).class_entry; 4411 } 4412 value = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1, ((OP1_TYPE == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); 4413 if (!value) { 4414 isset = 0; 4415 } 4416 } else { 4417 target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); 4418 if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) { 4419 isset = 0; 4420 } 4421 } 4422 4423 if (OP1_TYPE != IS_CONST && varname == &tmp) { 4424 zval_dtor(&tmp); 4425 } 4426 FREE_OP1(); 4427 } 4428 4429 if (opline->extended_value & ZEND_ISSET) { 4430 if (isset && Z_TYPE_PP(value) != IS_NULL) { 4431 ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); 4432 } else { 4433 ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); 4434 } 4435 } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { 4436 if (!isset || !i_zend_is_true(*value)) { 4437 ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); 4438 } else { 4439 ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); 4440 } 4441 } 4442 4443 CHECK_EXCEPTION(); 4444 ZEND_VM_NEXT_OPCODE(); 4445} 4446 4447ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|TMP|VAR|CV, int prop_dim) 4448{ 4449 USE_OPLINE 4450 zend_free_op free_op1, free_op2; 4451 zval **container; 4452 zval **value = NULL; 4453 int result = 0; 4454 ulong hval; 4455 zval *offset; 4456 4457 SAVE_OPLINE(); 4458 container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_IS); 4459 4460 offset = GET_OP2_ZVAL_PTR(BP_VAR_R); 4461 4462 if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { 4463 HashTable *ht; 4464 int isset = 0; 4465 4466 ht = Z_ARRVAL_PP(container); 4467 4468 switch (Z_TYPE_P(offset)) { 4469 case IS_DOUBLE: 4470 hval = zend_dval_to_lval(Z_DVAL_P(offset)); 4471 ZEND_VM_C_GOTO(num_index_prop); 4472 case IS_RESOURCE: 4473 case IS_BOOL: 4474 case IS_LONG: 4475 hval = Z_LVAL_P(offset); 4476ZEND_VM_C_LABEL(num_index_prop): 4477 if (zend_hash_index_find(ht, hval, (void **) &value) == SUCCESS) { 4478 isset = 1; 4479 } 4480 break; 4481 case IS_STRING: 4482 if (OP2_TYPE == IS_CONST) { 4483 hval = Z_HASH_P(offset); 4484 } else { 4485 if (!prop_dim) { 4486 ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_prop)); 4487 } 4488 if (IS_INTERNED(Z_STRVAL_P(offset))) { 4489 hval = INTERNED_HASH(Z_STRVAL_P(offset)); 4490 } else { 4491 hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); 4492 } 4493 } 4494 if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { 4495 isset = 1; 4496 } 4497 break; 4498 case IS_NULL: 4499 if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) { 4500 isset = 1; 4501 } 4502 break; 4503 default: 4504 zend_error(E_WARNING, "Illegal offset type in isset or empty"); 4505 break; 4506 } 4507 4508 if (opline->extended_value & ZEND_ISSET) { 4509 if (isset && Z_TYPE_PP(value) == IS_NULL) { 4510 result = 0; 4511 } else { 4512 result = isset; 4513 } 4514 } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { 4515 if (!isset || !i_zend_is_true(*value)) { 4516 result = 0; 4517 } else { 4518 result = 1; 4519 } 4520 } 4521 FREE_OP2(); 4522 } else if (Z_TYPE_PP(container) == IS_OBJECT) { 4523 if (IS_OP2_TMP_FREE()) { 4524 MAKE_REAL_ZVAL_PTR(offset); 4525 } 4526 if (prop_dim) { 4527 if (Z_OBJ_HT_P(*container)->has_property) { 4528 result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); 4529 } else { 4530 zend_error(E_NOTICE, "Trying to check property of non-object"); 4531 result = 0; 4532 } 4533 } else { 4534 if (Z_OBJ_HT_P(*container)->has_dimension) { 4535 result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); 4536 } else { 4537 zend_error(E_NOTICE, "Trying to check element of non-array"); 4538 result = 0; 4539 } 4540 } 4541 if (IS_OP2_TMP_FREE()) { 4542 zval_ptr_dtor(&offset); 4543 } else { 4544 FREE_OP2(); 4545 } 4546 } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ 4547 zval tmp; 4548 4549 if (Z_TYPE_P(offset) != IS_LONG) { 4550 if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ 4551 || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ 4552 && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { 4553 ZVAL_COPY_VALUE(&tmp, offset); 4554 zval_copy_ctor(&tmp); 4555 convert_to_long(&tmp); 4556 offset = &tmp; 4557 } else { 4558 /* can not be converted to proper offset, return "not set" */ 4559 result = 0; 4560 } 4561 } 4562 if (Z_TYPE_P(offset) == IS_LONG) { 4563 if (opline->extended_value & ZEND_ISSET) { 4564 if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { 4565 result = 1; 4566 } 4567 } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { 4568 if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { 4569 result = 1; 4570 } 4571 } 4572 } 4573 FREE_OP2(); 4574 } else { 4575 FREE_OP2(); 4576 } 4577 4578 Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL; 4579 if (opline->extended_value & ZEND_ISSET) { 4580 Z_LVAL(EX_T(opline->result.var).tmp_var) = result; 4581 } else { 4582 Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; 4583 } 4584 4585 FREE_OP1_VAR_PTR(); 4586 4587 CHECK_EXCEPTION(); 4588 ZEND_VM_NEXT_OPCODE(); 4589} 4590 4591ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 4592{ 4593 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, prop_dim, 0); 4594} 4595 4596ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 4597{ 4598 ZEND_VM_DISPATCH_TO_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, prop_dim, 1); 4599} 4600 4601ZEND_VM_HANDLER(79, ZEND_EXIT, CONST|TMP|VAR|UNUSED|CV, ANY) 4602{ 4603#if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED) 4604 USE_OPLINE 4605 4606 SAVE_OPLINE(); 4607 if (OP1_TYPE != IS_UNUSED) { 4608 zend_free_op free_op1; 4609 zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); 4610 4611 if (Z_TYPE_P(ptr) == IS_LONG) { 4612 EG(exit_status) = Z_LVAL_P(ptr); 4613 } else { 4614 zend_print_variable(ptr); 4615 } 4616 FREE_OP1(); 4617 } 4618#endif 4619 zend_bailout(); 4620 ZEND_VM_NEXT_OPCODE(); /* Never reached */ 4621} 4622 4623ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY) 4624{ 4625 USE_OPLINE 4626 4627 SAVE_OPLINE(); 4628 Z_LVAL(EX_T(opline->result.var).tmp_var) = EG(error_reporting); 4629 Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_LONG; /* shouldn't be necessary */ 4630 if (EX(old_error_reporting) == NULL) { 4631 EX(old_error_reporting) = &EX_T(opline->result.var).tmp_var; 4632 } 4633 4634 if (EG(error_reporting)) { 4635 do { 4636 EG(error_reporting) = 0; 4637 if (!EG(error_reporting_ini_entry)) { 4638 if (UNEXPECTED(zend_hash_find(EG(ini_directives), "error_reporting", sizeof("error_reporting"), (void **) &EG(error_reporting_ini_entry)) == FAILURE)) { 4639 break; 4640 } 4641 } 4642 if (!EG(error_reporting_ini_entry)->modified) { 4643 if (!EG(modified_ini_directives)) { 4644 ALLOC_HASHTABLE(EG(modified_ini_directives)); 4645 zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0); 4646 } 4647 if (EXPECTED(zend_hash_add(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting"), &EG(error_reporting_ini_entry), sizeof(zend_ini_entry*), NULL) == SUCCESS)) { 4648 EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value; 4649 EG(error_reporting_ini_entry)->orig_value_length = EG(error_reporting_ini_entry)->value_length; 4650 EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable; 4651 EG(error_reporting_ini_entry)->modified = 1; 4652 } 4653 } else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) { 4654 efree(EG(error_reporting_ini_entry)->value); 4655 } 4656 EG(error_reporting_ini_entry)->value = estrndup("0", sizeof("0")-1); 4657 EG(error_reporting_ini_entry)->value_length = sizeof("0")-1; 4658 } while (0); 4659 } 4660 CHECK_EXCEPTION(); 4661 ZEND_VM_NEXT_OPCODE(); 4662} 4663 4664ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY) 4665{ 4666 SAVE_OPLINE(); 4667 zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name, EX(op_array)->function_name); 4668 ZEND_VM_NEXT_OPCODE(); /* Never reached */ 4669} 4670 4671ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY) 4672{ 4673 USE_OPLINE 4674 zval restored_error_reporting; 4675 4676 SAVE_OPLINE(); 4677 if (!EG(error_reporting) && Z_LVAL(EX_T(opline->op1.var).tmp_var) != 0) { 4678 Z_TYPE(restored_error_reporting) = IS_LONG; 4679 Z_LVAL(restored_error_reporting) = Z_LVAL(EX_T(opline->op1.var).tmp_var); 4680 EG(error_reporting) = Z_LVAL(restored_error_reporting); 4681 convert_to_string(&restored_error_reporting); 4682 if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) { 4683 if (EXPECTED(EG(error_reporting_ini_entry)->modified && 4684 EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) { 4685 efree(EG(error_reporting_ini_entry)->value); 4686 } 4687 EG(error_reporting_ini_entry)->value = Z_STRVAL(restored_error_reporting); 4688 EG(error_reporting_ini_entry)->value_length = Z_STRLEN(restored_error_reporting); 4689 } else { 4690 zendi_zval_dtor(restored_error_reporting); 4691 } 4692 } 4693 if (EX(old_error_reporting) == &EX_T(opline->op1.var).tmp_var) { 4694 EX(old_error_reporting) = NULL; 4695 } 4696 CHECK_EXCEPTION(); 4697 ZEND_VM_NEXT_OPCODE(); 4698} 4699 4700ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY) 4701{ 4702 USE_OPLINE 4703 zend_free_op free_op1; 4704 zval *value; 4705 4706 SAVE_OPLINE(); 4707 value = GET_OP1_ZVAL_PTR(BP_VAR_R); 4708 4709 if (i_zend_is_true(value)) { 4710 ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value); 4711 if (!IS_OP1_TMP_FREE()) { 4712 zendi_zval_copy_ctor(EX_T(opline->result.var).tmp_var); 4713 } 4714 FREE_OP1_IF_VAR(); 4715#if DEBUG_ZEND>=2 4716 printf("Conditional jmp to %d\n", opline->op2.opline_num); 4717#endif 4718 ZEND_VM_JMP(opline->op2.jmp_addr); 4719 } 4720 4721 FREE_OP1(); 4722 CHECK_EXCEPTION(); 4723 ZEND_VM_NEXT_OPCODE(); 4724} 4725 4726ZEND_VM_HANDLER(158, ZEND_JMP_SET_VAR, CONST|TMP|VAR|CV, ANY) 4727{ 4728 USE_OPLINE 4729 zend_free_op free_op1; 4730 zval *value, *ret; 4731 4732 SAVE_OPLINE(); 4733 value = GET_OP1_ZVAL_PTR(BP_VAR_R); 4734 4735 if (i_zend_is_true(value)) { 4736 if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { 4737 Z_ADDREF_P(value); 4738 EX_T(opline->result.var).var.ptr = value; 4739 EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; 4740 } else { 4741 ALLOC_ZVAL(ret); 4742 INIT_PZVAL_COPY(ret, value); 4743 EX_T(opline->result.var).var.ptr = ret; 4744 EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; 4745 if (!IS_OP1_TMP_FREE()) { 4746 zval_copy_ctor(EX_T(opline->result.var).var.ptr); 4747 } 4748 } 4749 FREE_OP1_IF_VAR(); 4750#if DEBUG_ZEND>=2 4751 printf("Conditional jmp to %d\n", opline->op2.opline_num); 4752#endif 4753 ZEND_VM_JMP(opline->op2.jmp_addr); 4754 } 4755 4756 FREE_OP1(); 4757 CHECK_EXCEPTION(); 4758 ZEND_VM_NEXT_OPCODE(); 4759} 4760 4761ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY) 4762{ 4763 USE_OPLINE 4764 zend_free_op free_op1; 4765 zval *value; 4766 4767 SAVE_OPLINE(); 4768 value = GET_OP1_ZVAL_PTR(BP_VAR_R); 4769 4770 ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value); 4771 if (!IS_OP1_TMP_FREE()) { 4772 zval_copy_ctor(&EX_T(opline->result.var).tmp_var); 4773 } 4774 FREE_OP1_IF_VAR(); 4775 CHECK_EXCEPTION(); 4776 ZEND_VM_NEXT_OPCODE(); 4777} 4778 4779ZEND_VM_HANDLER(157, ZEND_QM_ASSIGN_VAR, CONST|TMP|VAR|CV, ANY) 4780{ 4781 USE_OPLINE 4782 zend_free_op free_op1; 4783 zval *value, *ret; 4784 4785 SAVE_OPLINE(); 4786 value = GET_OP1_ZVAL_PTR(BP_VAR_R); 4787 4788 if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { 4789 Z_ADDREF_P(value); 4790 EX_T(opline->result.var).var.ptr = value; 4791 EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; 4792 } else { 4793 ALLOC_ZVAL(ret); 4794 INIT_PZVAL_COPY(ret, value); 4795 EX_T(opline->result.var).var.ptr = ret; 4796 EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; 4797 if (!IS_OP1_TMP_FREE()) { 4798 zval_copy_ctor(EX_T(opline->result.var).var.ptr); 4799 } 4800 } 4801 4802 FREE_OP1_IF_VAR(); 4803 CHECK_EXCEPTION(); 4804 ZEND_VM_NEXT_OPCODE(); 4805} 4806 4807ZEND_VM_HANDLER(101, ZEND_EXT_STMT, ANY, ANY) 4808{ 4809 SAVE_OPLINE(); 4810 if (!EG(no_extensions)) { 4811 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, EX(op_array) TSRMLS_CC); 4812 } 4813 CHECK_EXCEPTION(); 4814 ZEND_VM_NEXT_OPCODE(); 4815} 4816 4817ZEND_VM_HANDLER(102, ZEND_EXT_FCALL_BEGIN, ANY, ANY) 4818{ 4819 SAVE_OPLINE(); 4820 if (!EG(no_extensions)) { 4821 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, EX(op_array) TSRMLS_CC); 4822 } 4823 CHECK_EXCEPTION(); 4824 ZEND_VM_NEXT_OPCODE(); 4825} 4826 4827ZEND_VM_HANDLER(103, ZEND_EXT_FCALL_END, ANY, ANY) 4828{ 4829 SAVE_OPLINE(); 4830 if (!EG(no_extensions)) { 4831 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, EX(op_array) TSRMLS_CC); 4832 } 4833 CHECK_EXCEPTION(); 4834 ZEND_VM_NEXT_OPCODE(); 4835} 4836 4837ZEND_VM_HANDLER(139, ZEND_DECLARE_CLASS, ANY, ANY) 4838{ 4839 USE_OPLINE 4840 4841 SAVE_OPLINE(); 4842 EX_T(opline->result.var).class_entry = do_bind_class(EX(op_array), opline, EG(class_table), 0 TSRMLS_CC); 4843 CHECK_EXCEPTION(); 4844 ZEND_VM_NEXT_OPCODE(); 4845} 4846 4847ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERITED_CLASS, ANY, ANY) 4848{ 4849 USE_OPLINE 4850 4851 SAVE_OPLINE(); 4852 EX_T(opline->result.var).class_entry = do_bind_inherited_class(EX(op_array), opline, EG(class_table), EX_T(opline->extended_value).class_entry, 0 TSRMLS_CC); 4853 CHECK_EXCEPTION(); 4854 ZEND_VM_NEXT_OPCODE(); 4855} 4856 4857ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY) 4858{ 4859 USE_OPLINE 4860 zend_class_entry **pce, **pce_orig; 4861 4862 SAVE_OPLINE(); 4863 if (zend_hash_quick_find(EG(class_table), Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv)+1, Z_HASH_P(opline->op2.zv), (void**)&pce) == FAILURE || 4864 (zend_hash_quick_find(EG(class_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), Z_HASH_P(opline->op1.zv), (void**)&pce_orig) == SUCCESS && 4865 *pce != *pce_orig)) { 4866 do_bind_inherited_class(EX(op_array), opline, EG(class_table), EX_T(opline->extended_value).class_entry, 0 TSRMLS_CC); 4867 } 4868 CHECK_EXCEPTION(); 4869 ZEND_VM_NEXT_OPCODE(); 4870} 4871 4872ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY) 4873{ 4874 USE_OPLINE 4875 4876 SAVE_OPLINE(); 4877 do_bind_function(EX(op_array), opline, EG(function_table), 0); 4878 CHECK_EXCEPTION(); 4879 ZEND_VM_NEXT_OPCODE(); 4880} 4881 4882ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY) 4883{ 4884 USE_OPLINE 4885 4886 SAVE_OPLINE(); 4887 if (++EG(ticks_count)>=opline->extended_value) { 4888 EG(ticks_count)=0; 4889 if (zend_ticks_function) { 4890 zend_ticks_function(opline->extended_value); 4891 } 4892 } 4893 CHECK_EXCEPTION(); 4894 ZEND_VM_NEXT_OPCODE(); 4895} 4896 4897ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, ANY) 4898{ 4899 USE_OPLINE 4900 zend_free_op free_op1; 4901 zval *expr; 4902 zend_bool result; 4903 4904 SAVE_OPLINE(); 4905 expr = GET_OP1_ZVAL_PTR(BP_VAR_R); 4906 4907 if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) { 4908 result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.var).class_entry TSRMLS_CC); 4909 } else { 4910 result = 0; 4911 } 4912 ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, result); 4913 FREE_OP1(); 4914 CHECK_EXCEPTION(); 4915 ZEND_VM_NEXT_OPCODE(); 4916} 4917 4918ZEND_VM_HANDLER(104, ZEND_EXT_NOP, ANY, ANY) 4919{ 4920 ZEND_VM_NEXT_OPCODE(); 4921} 4922 4923ZEND_VM_HANDLER(0, ZEND_NOP, ANY, ANY) 4924{ 4925 ZEND_VM_NEXT_OPCODE(); 4926} 4927 4928ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST) 4929{ 4930 USE_OPLINE 4931 zend_class_entry *ce = EX_T(opline->op1.var).class_entry; 4932 zend_class_entry *iface; 4933 4934 SAVE_OPLINE(); 4935 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 4936 iface = CACHED_PTR(opline->op2.literal->cache_slot); 4937 } else { 4938 iface = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv), opline->op2.literal + 1, opline->extended_value TSRMLS_CC); 4939 if (UNEXPECTED(iface == NULL)) { 4940 CHECK_EXCEPTION(); 4941 ZEND_VM_NEXT_OPCODE(); 4942 } 4943 CACHE_PTR(opline->op2.literal->cache_slot, ce); 4944 } 4945 4946 if (UNEXPECTED((iface->ce_flags & ZEND_ACC_INTERFACE) == 0)) { 4947 zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name); 4948 } 4949 zend_do_implement_interface(ce, iface TSRMLS_CC); 4950 4951 CHECK_EXCEPTION(); 4952 ZEND_VM_NEXT_OPCODE(); 4953} 4954 4955ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY) 4956{ 4957 USE_OPLINE 4958 zend_class_entry *ce = EX_T(opline->op1.var).class_entry; 4959 zend_class_entry *trait; 4960 4961 SAVE_OPLINE(); 4962 if (CACHED_PTR(opline->op2.literal->cache_slot)) { 4963 trait = CACHED_PTR(opline->op2.literal->cache_slot); 4964 } else { 4965 trait = zend_fetch_class_by_name(Z_STRVAL_P(opline->op2.zv), 4966 Z_STRLEN_P(opline->op2.zv), 4967 opline->op2.literal + 1, 4968 opline->extended_value TSRMLS_CC); 4969 if (UNEXPECTED(trait == NULL)) { 4970 CHECK_EXCEPTION(); 4971 ZEND_VM_NEXT_OPCODE(); 4972 } 4973 if (!((trait->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT)) { 4974 zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ce->name, trait->name); 4975 } 4976 CACHE_PTR(opline->op2.literal->cache_slot, trait); 4977 } 4978 4979 zend_do_implement_trait(ce, trait TSRMLS_CC); 4980 4981 CHECK_EXCEPTION(); 4982 ZEND_VM_NEXT_OPCODE(); 4983} 4984 4985ZEND_VM_HANDLER(155, ZEND_BIND_TRAITS, ANY, ANY) 4986{ 4987 USE_OPLINE 4988 zend_class_entry *ce = EX_T(opline->op1.var).class_entry; 4989 4990 SAVE_OPLINE(); 4991 zend_do_bind_traits(ce TSRMLS_CC); 4992 CHECK_EXCEPTION(); 4993 ZEND_VM_NEXT_OPCODE(); 4994} 4995 4996ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) 4997{ 4998 zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes; 4999 int i; 5000 zend_uint catch_op_num = 0; 5001 int catched = 0; 5002 zval restored_error_reporting; 5003 5004 void **stack_frame = (void**)(((char*)EX_Ts()) + 5005 (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T)); 5006 5007 while (zend_vm_stack_top(TSRMLS_C) != stack_frame) { 5008 zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C); 5009 zval_ptr_dtor(&stack_zval_p); 5010 } 5011 5012 for (i=0; i<EG(active_op_array)->last_try_catch; i++) { 5013 if (EG(active_op_array)->try_catch_array[i].try_op > op_num) { 5014 /* further blocks will not be relevant... */ 5015 break; 5016 } else if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) { 5017 catch_op_num = EX(op_array)->try_catch_array[i].catch_op; 5018 catched = 1; 5019 } 5020 } 5021 5022 while (EX(fbc)) { 5023 EX(called_scope) = (zend_class_entry*)zend_ptr_stack_pop(&EG(arg_types_stack)); 5024 if (EX(object)) { 5025 if (IS_CTOR_CALL(EX(called_scope))) { 5026 if (IS_CTOR_USED(EX(called_scope))) { 5027 Z_DELREF_P(EX(object)); 5028 } 5029 if (Z_REFCOUNT_P(EX(object)) == 1) { 5030 zend_object_store_ctor_failed(EX(object) TSRMLS_CC); 5031 } 5032 } 5033 zval_ptr_dtor(&EX(object)); 5034 } 5035 EX(called_scope) = DECODE_CTOR(EX(called_scope)); 5036 zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc)); 5037 } 5038 5039 for (i=0; i<EX(op_array)->last_brk_cont; i++) { 5040 if (EX(op_array)->brk_cont_array[i].start < 0) { 5041 continue; 5042 } else if (EX(op_array)->brk_cont_array[i].start > op_num) { 5043 /* further blocks will not be relevant... */ 5044 break; 5045 } else if (op_num < EX(op_array)->brk_cont_array[i].brk) { 5046 if (!catched || 5047 catch_op_num >= EX(op_array)->brk_cont_array[i].brk) { 5048 zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk]; 5049 5050 switch (brk_opline->opcode) { 5051 case ZEND_SWITCH_FREE: 5052 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { 5053 zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr); 5054 } 5055 break; 5056 case ZEND_FREE: 5057 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { 5058 zendi_zval_dtor(EX_T(brk_opline->op1.var).tmp_var); 5059 } 5060 break; 5061 } 5062 } 5063 } 5064 } 5065 5066 /* restore previous error_reporting value */ 5067 if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) { 5068 Z_TYPE(restored_error_reporting) = IS_LONG; 5069 Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting)); 5070 convert_to_string(&restored_error_reporting); 5071 zend_alter_ini_entry_ex("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC); 5072 zendi_zval_dtor(restored_error_reporting); 5073 } 5074 EX(old_error_reporting) = NULL; 5075 5076 if (!catched) { 5077 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); 5078 } else { 5079 ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]); 5080 ZEND_VM_CONTINUE(); 5081 } 5082} 5083 5084ZEND_VM_HANDLER(146, ZEND_VERIFY_ABSTRACT_CLASS, ANY, ANY) 5085{ 5086 USE_OPLINE 5087 5088 SAVE_OPLINE(); 5089 zend_verify_abstract_class(EX_T(opline->op1.var).class_entry TSRMLS_CC); 5090 CHECK_EXCEPTION(); 5091 ZEND_VM_NEXT_OPCODE(); 5092} 5093 5094ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY) 5095{ 5096 USE_OPLINE 5097 int ret; 5098 5099 SAVE_OPLINE(); 5100 ret = zend_user_opcode_handlers[opline->opcode](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL); 5101 LOAD_OPLINE(); 5102 5103 switch (ret) { 5104 case ZEND_USER_OPCODE_CONTINUE: 5105 ZEND_VM_CONTINUE(); 5106 case ZEND_USER_OPCODE_RETURN: 5107 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); 5108 case ZEND_USER_OPCODE_ENTER: 5109 ZEND_VM_ENTER(); 5110 case ZEND_USER_OPCODE_LEAVE: 5111 ZEND_VM_LEAVE(); 5112 case ZEND_USER_OPCODE_DISPATCH: 5113 ZEND_VM_DISPATCH(opline->opcode, opline); 5114 default: 5115 ZEND_VM_DISPATCH((zend_uchar)(ret & 0xff), opline); 5116 } 5117} 5118 5119ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) 5120{ 5121 USE_OPLINE 5122 zend_free_op free_op1, free_op2; 5123 zval *name; 5124 zval *val; 5125 zend_constant c; 5126 5127 SAVE_OPLINE(); 5128 name = GET_OP1_ZVAL_PTR(BP_VAR_R); 5129 val = GET_OP2_ZVAL_PTR(BP_VAR_R); 5130 5131 if ((Z_TYPE_P(val) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || Z_TYPE_P(val) == IS_CONSTANT_ARRAY) { 5132 zval tmp; 5133 zval *tmp_ptr = &tmp; 5134 5135 ZVAL_COPY_VALUE(&tmp, val); 5136 if (Z_TYPE_P(val) == IS_CONSTANT_ARRAY) { 5137 zval_copy_ctor(&tmp); 5138 } 5139 INIT_PZVAL(&tmp); 5140 zval_update_constant(&tmp_ptr, NULL TSRMLS_CC); 5141 c.value = *tmp_ptr; 5142 } else { 5143 INIT_PZVAL_COPY(&c.value, val); 5144 zval_copy_ctor(&c.value); 5145 } 5146 c.flags = CONST_CS; /* non persistent, case sensetive */ 5147 c.name = IS_INTERNED(Z_STRVAL_P(name)) ? Z_STRVAL_P(name) : zend_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name)); 5148 c.name_len = Z_STRLEN_P(name)+1; 5149 c.module_number = PHP_USER_CONSTANT; 5150 5151 if (zend_register_constant(&c TSRMLS_CC) == FAILURE) { 5152 } 5153 5154 FREE_OP1(); 5155 FREE_OP2(); 5156 CHECK_EXCEPTION(); 5157 ZEND_VM_NEXT_OPCODE(); 5158} 5159 5160ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED) 5161{ 5162 USE_OPLINE 5163 zend_function *op_array; 5164 5165 SAVE_OPLINE(); 5166 5167 if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), Z_HASH_P(opline->op1.zv), (void *) &op_array) == FAILURE) || 5168 UNEXPECTED(op_array->type != ZEND_USER_FUNCTION)) { 5169 zend_error_noreturn(E_ERROR, "Base lambda function for closure not found"); 5170 } 5171 5172 zend_create_closure(&EX_T(opline->result.var).tmp_var, op_array, EG(scope), EG(This) TSRMLS_CC); 5173 5174 CHECK_EXCEPTION(); 5175 ZEND_VM_NEXT_OPCODE(); 5176} 5177 5178ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED) 5179{ 5180 USE_OPLINE 5181 zval *var_ptr, *new_zv; 5182 5183 SAVE_OPLINE(); 5184 var_ptr = EX_T(opline->op1.var).var.ptr; 5185 if (Z_TYPE_P(var_ptr) != IS_OBJECT && 5186 !PZVAL_IS_REF(var_ptr) && 5187 Z_REFCOUNT_P(var_ptr) > 1) { 5188 5189 Z_DELREF_P(var_ptr); 5190 ALLOC_ZVAL(new_zv); 5191 INIT_PZVAL_COPY(new_zv, var_ptr); 5192 var_ptr = new_zv; 5193 zval_copy_ctor(var_ptr); 5194 EX_T(opline->op1.var).var.ptr = var_ptr; 5195 } 5196 ZEND_VM_NEXT_OPCODE(); 5197} 5198 5199ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper) 5200