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