|
24 | 24 | #include "Optimizer/zend_optimizer.h" |
25 | 25 | #include "Optimizer/zend_optimizer_internal.h" |
26 | 26 | #include "zend_API.h" |
| 27 | +#include "zend_compile.h" |
27 | 28 | #include "zend_constants.h" |
28 | 29 | #include "zend_execute.h" |
| 30 | +#include "zend_string.h" |
| 31 | +#include "zend_types.h" |
29 | 32 | #include "zend_vm.h" |
30 | 33 | #include "zend_extensions.h" |
31 | 34 |
|
|
35 | 38 | #define LITERAL_STATIC_METHOD 2 |
36 | 39 | #define LITERAL_STATIC_PROPERTY 3 |
37 | 40 |
|
| 41 | +// TODO: temp hack |
| 42 | +#define LITERAL_PNR_AND_KEY (1<<7) |
| 43 | + |
38 | 44 | typedef struct _literal_info { |
39 | 45 | uint8_t num_related; |
40 | 46 | } literal_info; |
@@ -245,7 +251,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx |
245 | 251 | break; |
246 | 252 | case ZEND_NEW: |
247 | 253 | if (opline->op1_type == IS_CONST) { |
248 | | - LITERAL_INFO(opline->op1.constant, 2); |
| 254 | + LITERAL_INFO(opline->op1.constant, 2 | LITERAL_PNR_AND_KEY); |
249 | 255 | } |
250 | 256 | break; |
251 | 257 | case ZEND_DECLARE_CLASS: |
@@ -312,6 +318,10 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx |
312 | 318 | memset(map, 0, op_array->last_literal * sizeof(int)); |
313 | 319 | for (i = 0; i < op_array->last_literal; i++) { |
314 | 320 | if (!info[i].num_related) { |
| 321 | + // TODO: temp hack |
| 322 | + if (Z_TYPE(op_array->literals[i]) == IS_PNR) { |
| 323 | + zend_pnr_destroy(Z_PNR(op_array->literals[i])); |
| 324 | + } |
315 | 325 | /* unset literal */ |
316 | 326 | zval_ptr_dtor_nogc(&op_array->literals[i]); |
317 | 327 | continue; |
@@ -443,6 +453,67 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx |
443 | 453 | } |
444 | 454 | break; |
445 | 455 | } |
| 456 | + case IS_PNR: { |
| 457 | + ZEND_ASSERT(info[i].num_related & LITERAL_PNR_AND_KEY); |
| 458 | + ZEND_ASSERT(Z_TYPE(op_array->literals[i+1]) == IS_STRING); |
| 459 | + |
| 460 | + uint8_t num_related = info[i].num_related & ~LITERAL_PNR_AND_KEY; |
| 461 | + ZEND_ASSERT(num_related == 2); |
| 462 | + |
| 463 | + zend_packed_name_reference pnr = Z_PNR(op_array->literals[i]); |
| 464 | + zend_string *base_key = Z_STR(op_array->literals[i+1]); |
| 465 | + zend_string *key; |
| 466 | + if (ZEND_PNR_IS_COMPLEX(pnr)) { |
| 467 | + key = ZEND_PNR_COMPLEX_GET_KEY(pnr); |
| 468 | + } else { |
| 469 | + key = ZEND_PNR_SIMPLE_GET_NAME(pnr); |
| 470 | + } |
| 471 | + key = zend_string_concat2( |
| 472 | + ZSTR_VAL(key), ZSTR_LEN(key)+1, |
| 473 | + ZSTR_VAL(base_key), ZSTR_LEN(base_key)); |
| 474 | + bias_key(key, 300 + num_related - 1); |
| 475 | + |
| 476 | + if ((pos = zend_hash_find(&hash, key)) != NULL) { |
| 477 | + ZEND_ASSERT(Z_TYPE(op_array->literals[Z_LVAL_P(pos)]) == IS_PNR && |
| 478 | + Z_TYPE(op_array->literals[Z_LVAL_P(pos)+1]) == IS_STRING && |
| 479 | + info[i].num_related == info[Z_LVAL_P(pos)].num_related); |
| 480 | + zend_string_release_ex(key, 0); |
| 481 | + map[i] = Z_LVAL_P(pos); |
| 482 | + zend_packed_name_reference pnr2 = Z_PNR(op_array->literals[i]); |
| 483 | + if (ZEND_PNR_IS_SIMPLE(pnr2)) { |
| 484 | + zend_string_release(ZEND_PNR_SIMPLE_GET_NAME(pnr2)); |
| 485 | + } else { |
| 486 | + zend_name_reference *class_ref = ZEND_PNR_COMPLEX_GET_REF(pnr2); |
| 487 | + zend_string_release(class_ref->name); |
| 488 | + zend_string_release(class_ref->key); |
| 489 | + } |
| 490 | + n = num_related; |
| 491 | + while (n > 1) { |
| 492 | + i++; |
| 493 | + zval_ptr_dtor_nogc(&op_array->literals[i]); |
| 494 | + n--; |
| 495 | + } |
| 496 | + } else { |
| 497 | + map[i] = j; |
| 498 | + ZVAL_LONG(&zv, j); |
| 499 | + zend_hash_add_new(&hash, key, &zv); |
| 500 | + zend_string_release_ex(key, 0); |
| 501 | + if (i != j) { |
| 502 | + op_array->literals[j] = op_array->literals[i]; |
| 503 | + info[j] = info[i]; |
| 504 | + } |
| 505 | + j++; |
| 506 | + n = num_related; |
| 507 | + while (n > 1) { |
| 508 | + i++; |
| 509 | + if (i != j) op_array->literals[j] = op_array->literals[i]; |
| 510 | + j++; |
| 511 | + n--; |
| 512 | + } |
| 513 | + } |
| 514 | + |
| 515 | + break; |
| 516 | + } |
446 | 517 | case IS_ARRAY: |
447 | 518 | ZEND_ASSERT(info[i].num_related == 1); |
448 | 519 | if (zend_hash_num_elements(Z_ARRVAL(op_array->literals[i])) == 0) { |
|
0 commit comments