Merge remote-tracking branch 'origin/master' into native-tls

* origin/master: (31 commits)
  Fixed C++ incompatibility
  update the certificate used for the test, as it expired recently
  Fixed immutable arrays support
  Fix counting of "R:" references in serialize()
  Remove dead code
  Test use($this) being an error
  Move list() condition into assign_znode
  typo
  NEWS
  Fix bug #68074 Allow to use system cipher list instead of hardcoded value
  Avoid double checks
  the order of the blocks should be Core, then exts in alphabetical order
  add missing NEWS entry for the phpdbg compilation fix
  add NEWS entry for #68088
  Make QM_ASSIGN, JMP_SET and CAST return IS_TMP_VAR.
  Removed useless helper
  Drop unused result argument
  Fix ct binding for cuf/cufa functions
  Fix detection of write to built-in function for references
  Test use of string names with \ prefix
  ...
This commit is contained in:
Anatol Belski 2014-09-24 21:39:49 +02:00
commit a2dd606942
46 changed files with 1125 additions and 1191 deletions

View File

@ -0,0 +1,10 @@
--TEST--
Cannot use built-in functions in write context (assignment)
--FILE--
<?php
strlen("foo")[0] = 1;
?>
--EXPECTF--
Fatal error: Cannot use result of built-in function in write context in %s on line %d

View File

@ -0,0 +1,10 @@
--TEST--
Cannot use built-in functions in write context (reference)
--FILE--
<?php
$ref =& strlen("foo");
?>
--EXPECTF--
Fatal error: Cannot use result of built-in function in write context in %s on line %d

View File

@ -0,0 +1,10 @@
--TEST--
Cannot access self::class when no class scope is active
--FILE--
<?php
var_dump(self::class);
?>
--EXPECTF--
Fatal error: Cannot access self::class when no class scope is active in %s on line %d

View File

@ -2,10 +2,76 @@
Dynamic Constant Expressions
--FILE--
<?php
const FOO = 1;
const BAR = FOO | 2;
echo BAR;
const C_0 = 0;
const C_1 = 1;
const C_foo = "foo";
const C_arr = [0 => 0, "foo" => "foo"];
const T_1 = C_1 | 2;
const T_2 = C_1 . "foo";
const T_3 = C_1 > 1;
const T_4 = C_1 >= 1;
const T_5 = -C_1;
const T_6 = +C_1;
const T_7 = +C_foo;
const T_8 = !C_1;
const T_9 = C_0 || 0;
const T_10 = C_1 || 0;
const T_11 = C_0 && 1;
const T_12 = C_1 && 1;
const T_13 = C_0 ? "foo" : "bar";
const T_14 = C_1 ? "foo" : "bar";
const T_15 = C_0 ?: "bar";
const T_16 = C_1 ?: "bar";
const T_17 = C_arr[0];
const T_18 = C_arr["foo"];
const T_19 = [
C_0,
"foo" => "foo",
42 => 42,
3.14 => 3.14,
null => null,
false => false,
true => true,
];
var_dump(
T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9, T_10,
T_11, T_12, T_13, T_14, T_15, T_16, T_17, T_18, T_19
);
?>
--EXPECTF--
3
--EXPECT--
int(3)
string(4) "1foo"
bool(false)
bool(true)
int(-1)
int(1)
int(0)
bool(false)
bool(false)
bool(true)
bool(false)
bool(true)
string(3) "bar"
string(3) "foo"
string(3) "bar"
int(1)
int(0)
string(3) "foo"
array(6) {
[0]=>
bool(false)
["foo"]=>
string(3) "foo"
[42]=>
int(42)
[3]=>
float(3.14)
[""]=>
NULL
[1]=>
bool(true)
}

View File

@ -0,0 +1,11 @@
--TEST--
Dynamic class names can't be used in compile-time constant refs
--FILE--
<?php
$foo = 'test';
const C = $foo::BAR;
?>
--EXPECTF--
Fatal error: Dynamic class names are not allowed in compile-time class constant references in %s on line %d

View File

@ -0,0 +1,11 @@
--TEST--
Can't use arrays as key for constant array
--FILE--
<?php
const C1 = 1; // force dynamic evaluation
const C2 = [C1, [] => 1];
?>
--EXPECTF--
Fatal error: Illegal offset type in %s on line %d

View File

@ -0,0 +1,10 @@
--TEST--
Cannot use static::FOO in constant expressions
--FILE--
<?php
const C = static::FOO;
?>
--EXPECTF--
Fatal error: "static::" is not allowed in compile-time constants in %s on line %d

View File

@ -0,0 +1,12 @@
--TEST--
Duplicate labels are not allowed
--FILE--
<?php
foo:
foo:
goto foo;
?>
--EXPECTF--
Fatal error: Label 'foo' already defined in %s on line %d

View File

@ -0,0 +1,26 @@
--TEST--
Test use of magic constants in the global scope
--FILE--
<?php
var_dump(
__LINE__,
__FILE__,
__DIR__,
__FUNCTION__,
__METHOD__,
__CLASS__,
__TRAIT__,
__NAMESPACE__
);
?>
--EXPECTF--
int(4)
string(%d) "%s"
string(%d) "%s"
string(0) ""
string(0) ""
string(0) ""
string(0) ""
string(0) ""

View File

@ -0,0 +1,10 @@
--TEST--
Cannot use special class name as namespace
--FILE--
<?php
namespace self;
?>
--EXPECTF--
Fatal error: Cannot use 'self' as namespace name in %s on line %d

View File

@ -0,0 +1,10 @@
--TEST--
Cannot use special class name as alias
--FILE--
<?php
use Foo\Bar as self;
?>
--EXPECTF--
Fatal error: Cannot use Foo\Bar as self because 'self' is a special class name in %s on line %d

View File

@ -0,0 +1,10 @@
--TEST--
Cannot use special class name as trait name
--FILE--
<?php
trait self {}
?>
--EXPECTF--
Fatal error: Cannot use 'self' as class name as it is reserved in %s on line %d

View File

@ -0,0 +1,14 @@
--TEST--
Cannot use $this as lexical variable
--FILE--
<?php
class Foo {
public function fn() {
return function() use ($this) {};
}
}
?>
--EXPECTF--
Fatal error: Cannot use $this as lexical variable in %s on line %d

View File

@ -34,6 +34,7 @@ $obj = new Test;
['Test', 'id']()()('var_dump')(11);
'id'()('id')('var_dump')(12);
('i' . 'd')()('var_dump')(13);
'\id'('var_dump')(14);
?>
--EXPECT--
@ -51,3 +52,4 @@ int(10)
int(11)
int(12)
int(13)
int(14)

View File

@ -19,6 +19,7 @@ var_dump($A_str::$b);
var_dump($A_obj::$b);
var_dump(('A' . '')::$b);
var_dump('A'::$b);
var_dump('\A'::$b);
var_dump('A'[0]::$b);
var_dump(A::$$b_str);
var_dump(A::$$c_str[1]);
@ -33,5 +34,6 @@ int(0)
int(0)
int(0)
int(0)
int(0)
int(1)
int(0)

View File

@ -216,79 +216,10 @@ ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy TSRMLS_DC) /*
{
if (Z_TYPE_P(expr) == IS_STRING) {
return 0;
} else {
ZVAL_STR(expr_copy, _zval_get_string_func(expr TSRMLS_CC));
return 1;
}
again:
switch (Z_TYPE_P(expr)) {
case IS_NULL:
case IS_FALSE:
ZVAL_EMPTY_STRING(expr_copy);
break;
case IS_TRUE:
if (CG(one_char_string)['1']) {
ZVAL_INTERNED_STR(expr_copy, CG(one_char_string)['1']);
} else {
ZVAL_NEW_STR(expr_copy, zend_string_init("1", 1, 0));
}
break;
case IS_RESOURCE: {
char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
int len;
len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, Z_RES_HANDLE_P(expr));
ZVAL_NEW_STR(expr_copy, zend_string_init(buf, len, 0));
}
break;
case IS_ARRAY:
zend_error(E_NOTICE, "Array to string conversion");
// TODO: use interned string ???
ZVAL_NEW_STR(expr_copy, zend_string_init("Array", sizeof("Array") - 1, 0));
break;
case IS_OBJECT:
if (Z_OBJ_HANDLER_P(expr, cast_object)) {
Z_ADDREF_P(expr);
if (Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
zval_ptr_dtor(expr);
break;
}
zval_ptr_dtor(expr);
}
if (!Z_OBJ_HANDLER_P(expr, cast_object) && Z_OBJ_HANDLER_P(expr, get)) {
zval rv;
zval *z = Z_OBJ_HANDLER_P(expr, get)(expr, &rv TSRMLS_CC);
Z_ADDREF_P(z);
if (Z_TYPE_P(z) != IS_OBJECT) {
if (zend_make_printable_zval(z, expr_copy TSRMLS_CC)) {
zval_ptr_dtor(z);
} else {
ZVAL_ZVAL(expr_copy, z, 0, 1);
}
return 1;
}
zval_ptr_dtor(z);
}
zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", Z_OBJCE_P(expr)->name->val);
ZVAL_EMPTY_STRING(expr_copy);
break;
case IS_DOUBLE:
ZVAL_DUP(expr_copy, expr);
zend_locale_sprintf_double(expr_copy ZEND_FILE_LINE_CC);
break;
case IS_REFERENCE:
expr = Z_REFVAL_P(expr);
if (Z_TYPE_P(expr) == IS_STRING) {
ZVAL_STR_COPY(expr_copy, Z_STR_P(expr));
return 1;
}
goto again;
break;
default:
ZVAL_DUP(expr_copy, expr);
convert_to_string(expr_copy);
break;
}
return 1;
}
/* }}} */

View File

@ -220,7 +220,9 @@ static zend_always_inline zval *zend_ast_get_zval(zend_ast *ast) {
return &((zend_ast_zval *) ast)->val;
}
static zend_always_inline zend_string *zend_ast_get_str(zend_ast *ast) {
return Z_STR_P(zend_ast_get_zval(ast));
zval *zv = zend_ast_get_zval(ast);
ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
return Z_STR_P(zv);
}
static zend_always_inline uint32_t zend_ast_get_num_children(zend_ast *ast) {

View File

@ -1773,23 +1773,8 @@ ZEND_FUNCTION(get_defined_functions)
zend_hash_apply_with_arguments(EG(function_table) TSRMLS_CC, copy_function_name, 2, &internal, &user);
ret = zend_hash_str_add_new(Z_ARRVAL_P(return_value), "internal", sizeof("internal")-1, &internal);
if (!ret) {
zval_ptr_dtor(&internal);
zval_ptr_dtor(&user);
zval_dtor(return_value);
zend_error(E_WARNING, "Cannot add internal functions to return value from get_defined_functions()");
RETURN_FALSE;
}
ret = zend_hash_str_add_new(Z_ARRVAL_P(return_value), "user", sizeof("user")-1, &user);
if (!ret) {
zval_ptr_dtor(&user);
zval_dtor(return_value);
zend_error(E_WARNING, "Cannot add user functions to return value from get_defined_functions()");
RETURN_FALSE;
}
zend_hash_str_add_new(Z_ARRVAL_P(return_value), "internal", sizeof("internal")-1, &internal);
zend_hash_str_add_new(Z_ARRVAL_P(return_value), "user", sizeof("user")-1, &user);
}
/* }}} */

View File

@ -319,82 +319,57 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC) /* {{{ */
}
/* }}} */
static int zend_add_func_name_literal(zend_op_array *op_array, zval *zv TSRMLS_DC) /* {{{ */
static inline int zend_add_literal_string(zend_op_array *op_array, zend_string **str TSRMLS_DC) /* {{{ */
{
int ret;
zend_string *lc_name;
zval c;
if (op_array->last_literal > 0 &&
&op_array->literals[op_array->last_literal - 1] == zv &&
Z_CACHE_SLOT(op_array->literals[op_array->last_literal - 1]) == -1) {
/* we already have function name as last literal (do nothing) */
ret = op_array->last_literal - 1;
} else {
ret = zend_add_literal(op_array, zv TSRMLS_CC);
}
lc_name = zend_string_alloc(Z_STRLEN_P(zv), 0);
zend_str_tolower_copy(lc_name->val, Z_STRVAL_P(zv), Z_STRLEN_P(zv));
ZVAL_NEW_STR(&c, lc_name);
zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
return ret;
}
/* }}} */
static int zend_add_ns_func_name_literal(zend_op_array *op_array, zval *zv TSRMLS_DC) /* {{{ */
{
int ret;
zend_string *lc_name;
const char *ns_separator;
int lc_len;
zval c;
if (op_array->last_literal > 0 &&
&op_array->literals[op_array->last_literal - 1] == zv &&
Z_CACHE_SLOT(op_array->literals[op_array->last_literal - 1]) == -1) {
/* we already have function name as last literal (do nothing) */
ret = op_array->last_literal - 1;
} else {
ret = zend_add_literal(op_array, zv TSRMLS_CC);
}
lc_name = zend_string_alloc(Z_STRLEN_P(zv), 0);
zend_str_tolower_copy(lc_name->val, Z_STRVAL_P(zv), Z_STRLEN_P(zv));
ZVAL_NEW_STR(&c, lc_name);
zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
ns_separator = (const char*)zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv));
if (ns_separator != NULL) {
ns_separator += 1;
lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv));
lc_name = zend_string_alloc(lc_len, 0);
zend_str_tolower_copy(lc_name->val, ns_separator, lc_len);
ZVAL_NEW_STR(&c, lc_name);
zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
}
return ret;
}
/* }}} */
static int zend_add_class_name_literal(zend_op_array *op_array, zend_string *name TSRMLS_DC) /* {{{ */ {
int ret;
zend_string *lc_name;
zval zv;
ZVAL_STR(&zv, name);
ZVAL_STR(&zv, *str);
ret = zend_add_literal(op_array, &zv TSRMLS_CC);
name = Z_STR(zv); /* Load new name string in case it was interned */
*str = Z_STR(zv);
return ret;
}
lc_name = zend_string_alloc(name->len, 0);
static int zend_add_func_name_literal(zend_op_array *op_array, zend_string *name TSRMLS_DC) /* {{{ */
{
int ret = zend_add_literal_string(op_array, &name TSRMLS_CC);
zend_string *lc_name = zend_string_alloc(name->len, 0);
zend_str_tolower_copy(lc_name->val, name->val, name->len);
zend_add_literal_string(op_array, &lc_name TSRMLS_CC);
ZVAL_NEW_STR(&zv, lc_name);
zend_add_literal(CG(active_op_array), &zv TSRMLS_CC);
return ret;
}
/* }}} */
static int zend_add_ns_func_name_literal(zend_op_array *op_array, zend_string *name TSRMLS_DC) /* {{{ */
{
const char *ns_separator;
int ret = zend_add_literal_string(op_array, &name TSRMLS_CC);
zend_string *lc_name = zend_string_alloc(name->len, 0);
zend_str_tolower_copy(lc_name->val, name->val, name->len);
zend_add_literal_string(op_array, &lc_name TSRMLS_CC);
ns_separator = zend_memrchr(name->val, '\\', name->len);
if (ns_separator != NULL) {
size_t len = name->len - (ns_separator - name->val + 1);
lc_name = zend_string_alloc(len, 0);
zend_str_tolower_copy(lc_name->val, ns_separator + 1, len);
zend_add_literal_string(op_array, &lc_name TSRMLS_CC);
}
return ret;
}
/* }}} */
static int zend_add_class_name_literal(zend_op_array *op_array, zend_string *name TSRMLS_DC) /* {{{ */
{
int ret = zend_add_literal_string(op_array, &name TSRMLS_CC);
zend_string *lc_name = zend_string_alloc(name->len, 0);
zend_str_tolower_copy(lc_name->val, name->val, name->len);
zend_add_literal_string(op_array, &lc_name TSRMLS_CC);
zend_alloc_cache_slot(ret TSRMLS_CC);
@ -402,72 +377,44 @@ static int zend_add_class_name_literal(zend_op_array *op_array, zend_string *nam
}
/* }}} */
static int zend_add_const_name_literal(zend_op_array *op_array, zval *zv, int unqualified TSRMLS_DC) /* {{{ */
static int zend_add_const_name_literal(zend_op_array *op_array, zend_string *name, zend_bool unqualified TSRMLS_DC) /* {{{ */
{
int ret;
char *name;
zend_string *tmp_name;
const char *ns_separator;
int name_len, ns_len;
zval c;
if (op_array->last_literal > 0 &&
&op_array->literals[op_array->last_literal - 1] == zv &&
Z_CACHE_SLOT(op_array->literals[op_array->last_literal - 1]) == -1) {
/* we already have function name as last literal (do nothing) */
ret = op_array->last_literal - 1;
} else {
ret = zend_add_literal(op_array, zv TSRMLS_CC);
}
int ret = zend_add_literal_string(op_array, &name TSRMLS_CC);
/* skip leading '\\' */
if (Z_STRVAL_P(zv)[0] == '\\') {
name_len = Z_STRLEN_P(zv) - 1;
name = Z_STRVAL_P(zv) + 1;
} else {
name_len = Z_STRLEN_P(zv);
name = Z_STRVAL_P(zv);
}
ns_separator = zend_memrchr(name, '\\', name_len);
if (ns_separator) {
ns_len = ns_separator - name;
} else {
ns_len = 0;
}
size_t ns_len = 0, after_ns_len = name->len;
const char *after_ns = zend_memrchr(name->val, '\\', name->len);
if (after_ns) {
after_ns += 1;
ns_len = after_ns - name->val - 1;
after_ns_len = name->len - ns_len - 1;
if (ns_len) {
/* lowercased namespace name & original constant name */
tmp_name = zend_string_init(name, name_len, 0);
tmp_name = zend_string_init(name->val, name->len, 0);
zend_str_tolower(tmp_name->val, ns_len);
ZVAL_NEW_STR(&c, tmp_name);
zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
zend_add_literal_string(op_array, &tmp_name TSRMLS_CC);
/* lowercased namespace name & lowercased constant name */
tmp_name = zend_string_alloc(name_len, 0);
zend_str_tolower_copy(tmp_name->val, name, name_len);
ZVAL_NEW_STR(&c, tmp_name);
zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
}
tmp_name = zend_string_alloc(name->len, 0);
zend_str_tolower_copy(tmp_name->val, name->val, name->len);
zend_add_literal_string(op_array, &tmp_name TSRMLS_CC);
if (ns_len) {
if (!unqualified) {
return ret;
}
ns_len++;
name += ns_len;
name_len -= ns_len;
} else {
after_ns = name->val;
}
/* original constant name */
tmp_name = zend_string_init(name, name_len, 0);
ZVAL_NEW_STR(&c, tmp_name);
zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
/* original unqualified constant name */
tmp_name = zend_string_init(after_ns, after_ns_len, 0);
zend_add_literal_string(op_array, &tmp_name TSRMLS_CC);
/* lowercased constant name */
tmp_name = zend_string_alloc(name_len, 0);
zend_str_tolower_copy(tmp_name->val, name, name_len);
ZVAL_NEW_STR(&c, tmp_name);
zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
/* lowercased unqualified constant name */
tmp_name = zend_string_alloc(after_ns_len, 0);
zend_str_tolower_copy(tmp_name->val, after_ns, after_ns_len);
zend_add_literal_string(op_array, &tmp_name TSRMLS_CC);
return ret;
}
@ -536,8 +483,7 @@ void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */
&& opline->result.var == op1->u.op.var) {
if (opline->opcode == ZEND_FETCH_R ||
opline->opcode == ZEND_FETCH_DIM_R ||
opline->opcode == ZEND_FETCH_OBJ_R ||
opline->opcode == ZEND_QM_ASSIGN) {
opline->opcode == ZEND_FETCH_OBJ_R) {
/* It's very rare and useless case. It's better to use
additional FREE opcode and simplify the FETCH handlers
their selves */
@ -859,7 +805,7 @@ static int generate_free_loop_var(znode *var TSRMLS_DC) /* {{{ */
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = var->op_type == IS_TMP_VAR ? ZEND_FREE : ZEND_SWITCH_FREE;
opline->opcode = ZEND_FREE;
SET_NODE(opline->op1, var);
SET_UNUSED(opline->op2);
}
@ -1226,14 +1172,12 @@ static zend_constant *zend_get_ct_const(zend_string *name, int all_internal_cons
}
/* }}} */
static int zend_constant_ct_subst(znode *result, zval *const_name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
static int zend_constant_ct_subst(zval *result, zend_string *name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
{
zend_constant *c = zend_get_ct_const(Z_STR_P(const_name),
all_internal_constants_substitution TSRMLS_CC);
zend_constant *c = zend_get_ct_const(name, all_internal_constants_substitution TSRMLS_CC);
if (c) {
result->op_type = IS_CONST;
ZVAL_DUP(&result->u.constant, &c->value);
ZVAL_DUP(result, &c->value);
return 1;
}
return 0;
@ -1389,9 +1333,6 @@ again:
if (LANG_SCNG(yy_text)[LANG_SCNG(yy_leng)-1] != '>') {
CG(increment_lineno) = 1;
}
if (CG(has_bracketed_namespaces) && !CG(in_namespace)) {
goto again;
}
retval = ';'; /* implicit ; */
break;
case T_OPEN_TAG_WITH_ECHO:
@ -1766,7 +1707,9 @@ static zend_op *zend_emit_op_tmp(znode *result, zend_uchar opcode, znode *op1, z
SET_NODE(opline->op2, op2);
}
zend_make_tmp_result(result, opline TSRMLS_CC);
if (result) {
zend_make_tmp_result(result, opline TSRMLS_CC);
}
return opline;
}
@ -2068,13 +2011,18 @@ static void zend_separate_if_call_and_write(znode *node, zend_ast *ast, uint32_t
void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type TSRMLS_DC);
void zend_compile_assign(znode *result, zend_ast *ast TSRMLS_DC);
static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node TSRMLS_DC);
static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node TSRMLS_DC) /* {{{ */
{
znode dummy_node;
zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast,
zend_ast_create_znode(value_node));
zend_compile_assign(&dummy_node, assign_ast TSRMLS_CC);
if (var_ast->kind == ZEND_AST_LIST) {
zend_compile_list_assign(&dummy_node, var_ast, value_node TSRMLS_CC);
} else {
zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast,
zend_ast_create_znode(value_node));
zend_compile_assign(&dummy_node, assign_ast TSRMLS_CC);
}
zend_do_free(&dummy_node TSRMLS_CC);
}
/* }}} */
@ -2256,13 +2204,7 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n
get_list_fetch_opcode(expr_node->op_type), expr_node, &dim_node TSRMLS_CC);
opline->extended_value |= ZEND_FETCH_ADD_LOCK;
if (var_ast->kind != ZEND_AST_LIST) {
zend_emit_assign_znode(var_ast, &fetch_result TSRMLS_CC);
} else {
znode assign_result;
zend_compile_list_assign(&assign_result, var_ast, &fetch_result TSRMLS_CC);
zend_do_free(&assign_result TSRMLS_CC);
}
zend_emit_assign_znode(var_ast, &fetch_result TSRMLS_CC);
}
*result = *expr_node;
}
@ -2380,6 +2322,10 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
zend_compile_var(&target_node, target_ast, BP_VAR_W TSRMLS_CC);
zend_compile_var(&source_node, source_ast, BP_VAR_REF TSRMLS_CC);
if (source_node.op_type != IS_VAR && zend_is_call(source_ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use result of built-in function in write context");
}
opline = zend_emit_op(result, ZEND_ASSIGN_REF, &target_node, &source_node TSRMLS_CC);
if (!result) {
opline->result_type |= EXT_TYPE_UNUSED;
@ -2593,7 +2539,7 @@ void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast TS
SET_UNUSED(opline->op1);
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_ns_func_name_literal(
CG(active_op_array), &name_node->u.constant TSRMLS_CC);
CG(active_op_array), Z_STR(name_node->u.constant) TSRMLS_CC);
zend_alloc_cache_slot(opline->op2.constant TSRMLS_CC);
zend_compile_call_common(result, args_ast, NULL TSRMLS_CC);
@ -2607,8 +2553,8 @@ void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_a
SET_UNUSED(opline->op1);
if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) {
opline->op2_type = IS_CONST;
opline->op2.constant
= zend_add_func_name_literal(CG(active_op_array), &name_node->u.constant TSRMLS_CC);
opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
Z_STR(name_node->u.constant) TSRMLS_CC);
zend_alloc_cache_slot(opline->op2.constant TSRMLS_CC);
} else {
SET_NODE(opline->op2, name_node);
@ -2694,13 +2640,13 @@ int zend_compile_func_defined(znode *result, zend_ast_list *args TSRMLS_DC) /* {
}
/* }}} */
static int zend_try_compile_ct_bound_init_user_func(znode *result, zend_ast *name_ast, uint32_t num_args TSRMLS_DC) /* {{{ */
static int zend_try_compile_ct_bound_init_user_func(zend_ast *name_ast, uint32_t num_args TSRMLS_DC) /* {{{ */
{
zend_string *name, *lcname;
zend_function *fbc;
zend_op *opline;
if (name_ast->kind != ZEND_AST_CONST || Z_TYPE_P(zend_ast_get_zval(name_ast)) != IS_STRING) {
if (name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(name_ast)) != IS_STRING) {
return FAILURE;
}
@ -2717,20 +2663,22 @@ static int zend_try_compile_ct_bound_init_user_func(znode *result, zend_ast *nam
}
opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, NULL TSRMLS_CC);
opline->extended_value = num_args;
opline->op2_type = IS_CONST;
LITERAL_STR(opline->op2, lcname);
opline->extended_value = num_args;
zend_alloc_cache_slot(opline->op2.constant TSRMLS_CC);
return SUCCESS;
}
/* }}} */
static void zend_compile_init_user_func(znode *result, zend_ast *name_ast, uint32_t num_args, zend_string *orig_func_name TSRMLS_DC) /* {{{ */
static void zend_compile_init_user_func(zend_ast *name_ast, uint32_t num_args, zend_string *orig_func_name TSRMLS_DC) /* {{{ */
{
zend_op *opline;
znode name_node;
if (zend_try_compile_ct_bound_init_user_func(result, name_ast, num_args TSRMLS_CC) == SUCCESS) {
if (zend_try_compile_ct_bound_init_user_func(name_ast, num_args TSRMLS_CC) == SUCCESS) {
return;
}
@ -2752,7 +2700,7 @@ int zend_compile_func_cufa(znode *result, zend_ast_list *args, zend_string *lcna
return FAILURE;
}
zend_compile_init_user_func(NULL, args->child[0], 1, lcname TSRMLS_CC);
zend_compile_init_user_func(args->child[0], 1, lcname TSRMLS_CC);
zend_compile_expr(&arg_node, args->child[1] TSRMLS_CC);
zend_emit_op(NULL, ZEND_SEND_ARRAY, &arg_node, NULL TSRMLS_CC);
zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL TSRMLS_CC);
@ -2770,7 +2718,7 @@ int zend_compile_func_cuf(znode *result, zend_ast_list *args, zend_string *lcnam
return FAILURE;
}
zend_compile_init_user_func(NULL, args->child[0], args->children - 1, lcname TSRMLS_CC);
zend_compile_init_user_func(args->child[0], args->children - 1, lcname TSRMLS_CC);
for (i = 1; i < args->children; ++i) {
zend_ast *arg_ast = args->child[i];
znode arg_node;
@ -2920,8 +2868,8 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type TSRMLS
}
opline->op2_type = IS_CONST;
opline->op2.constant =
zend_add_func_name_literal(CG(active_op_array), &method_node.u.constant TSRMLS_CC);
opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
Z_STR(method_node.u.constant) TSRMLS_CC);
zend_alloc_polymorphic_cache_slot(opline->op2.constant TSRMLS_CC);
} else {
SET_NODE(opline->op2, &method_node);
@ -2975,8 +2923,8 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type TSRMLS
if (method_node.op_type == IS_CONST) {
opline->op2_type = IS_CONST;
opline->op2.constant =
zend_add_func_name_literal(CG(active_op_array), &method_node.u.constant TSRMLS_CC);
opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
Z_STR(method_node.u.constant) TSRMLS_CC);
if (opline->op1_type == IS_CONST) {
zend_alloc_cache_slot(opline->op2.constant TSRMLS_CC);
} else {
@ -3252,11 +3200,9 @@ void zend_compile_goto(zend_ast *ast TSRMLS_DC) /* {{{ */
void zend_compile_label(zend_ast *ast TSRMLS_DC) /* {{{ */
{
zval *label = zend_ast_get_zval(ast->child[0]);
zend_string *label = zend_ast_get_str(ast->child[0]);
zend_label dest;
ZEND_ASSERT(Z_TYPE_P(label) == IS_STRING);
if (!CG(context).labels) {
ALLOC_HASHTABLE(CG(context).labels);
zend_hash_init(CG(context).labels, 8, NULL, ptr_dtor, 0);
@ -3265,8 +3211,8 @@ void zend_compile_label(zend_ast *ast TSRMLS_DC) /* {{{ */
dest.brk_cont = CG(context).current_brk_cont;
dest.opline_num = get_next_op_number(CG(active_op_array));
if (!zend_hash_add_mem(CG(context).labels, Z_STR_P(label), &dest, sizeof(zend_label))) {
zend_error_noreturn(E_COMPILE_ERROR, "Label '%s' already defined", Z_STRVAL_P(label));
if (!zend_hash_add_mem(CG(context).labels, label, &dest, sizeof(zend_label))) {
zend_error_noreturn(E_COMPILE_ERROR, "Label '%s' already defined", label->val);
}
}
/* }}} */
@ -3383,7 +3329,7 @@ void zend_compile_foreach(zend_ast *ast TSRMLS_DC) /* {{{ */
zend_bool is_variable = zend_is_variable(expr_ast) && !zend_is_call(expr_ast)
&& zend_can_write_to_variable(expr_ast);
znode expr_node, reset_node, value_node, key_node, dummy_node;
znode expr_node, reset_node, value_node, key_node;
zend_op *opline;
uint32_t opnum_reset, opnum_fetch;
@ -3441,10 +3387,7 @@ void zend_compile_foreach(zend_ast *ast TSRMLS_DC) /* {{{ */
zend_make_tmp_result(&key_node, opline TSRMLS_CC);
}
if (value_ast->attr == ZEND_AST_LIST) {
zend_compile_list_assign(&dummy_node, value_ast, &value_node TSRMLS_CC);
zend_do_free(&dummy_node TSRMLS_CC);
} else if (by_ref) {
if (by_ref) {
zend_emit_assign_ref_znode(value_ast, &value_node TSRMLS_CC);
} else {
zend_emit_assign_znode(value_ast, &value_node TSRMLS_CC);
@ -3586,7 +3529,7 @@ void zend_compile_switch(zend_ast *ast TSRMLS_DC) /* {{{ */
zend_end_loop(get_next_op_number(CG(active_op_array)), 1 TSRMLS_CC);
if (expr_node.op_type == IS_VAR || expr_node.op_type == IS_TMP_VAR) {
zend_emit_op(NULL, expr_node.op_type == IS_TMP_VAR ? ZEND_FREE : ZEND_SWITCH_FREE,
zend_emit_op(NULL, ZEND_FREE,
&expr_node, NULL TSRMLS_CC);
} else if (expr_node.op_type == IS_CONST) {
zval_dtor(&expr_node.u.constant);
@ -5309,7 +5252,7 @@ void zend_compile_cast(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
zend_compile_expr(&expr_node, expr_ast TSRMLS_CC);
opline = zend_emit_op(result, ZEND_CAST, &expr_node, NULL TSRMLS_CC);
opline = zend_emit_op_tmp(result, ZEND_CAST, &expr_node, NULL TSRMLS_CC);
opline->extended_value = ast->attr;
}
/* }}} */
@ -5328,13 +5271,13 @@ static void zend_compile_shorthand_conditional(znode *result, zend_ast *ast TSRM
zend_compile_expr(&cond_node, cond_ast TSRMLS_CC);
opnum_jmp_set = get_next_op_number(CG(active_op_array));
zend_emit_op(result, ZEND_JMP_SET, &cond_node, NULL TSRMLS_CC);
zend_emit_op_tmp(result, ZEND_JMP_SET, &cond_node, NULL TSRMLS_CC);
zend_compile_expr(&false_node, false_ast TSRMLS_CC);
opline_jmp_set = &CG(active_op_array)->opcodes[opnum_jmp_set];
opline_jmp_set->op2.opline_num = get_next_op_number(CG(active_op_array)) + 1;
opline_qm_assign = zend_emit_op(NULL, ZEND_QM_ASSIGN, &false_node, NULL TSRMLS_CC);
opline_qm_assign = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &false_node, NULL TSRMLS_CC);
SET_NODE(opline_qm_assign->result, result);
}
/* }}} */
@ -5361,7 +5304,7 @@ void zend_compile_conditional(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
zend_compile_expr(&true_node, true_ast TSRMLS_CC);
opnum_qm_assign1 = get_next_op_number(CG(active_op_array));
zend_emit_op(result, ZEND_QM_ASSIGN, &true_node, NULL TSRMLS_CC);
zend_emit_op_tmp(result, ZEND_QM_ASSIGN, &true_node, NULL TSRMLS_CC);
opnum_jmp = zend_emit_jump(0 TSRMLS_CC);
@ -5643,17 +5586,17 @@ void zend_compile_array(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
void zend_compile_const(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
{
zend_ast *name_ast = ast->child[0];
zend_string *orig_name = zend_ast_get_str(name_ast);
zend_bool is_fully_qualified;
zval resolved_name;
zend_op *opline;
ZVAL_STR(&resolved_name, zend_resolve_const_name(
orig_name, name_ast->attr, &is_fully_qualified TSRMLS_CC));
zend_bool is_fully_qualified;
zend_string *orig_name = zend_ast_get_str(name_ast);
zend_string *resolved_name = zend_resolve_const_name(
orig_name, name_ast->attr, &is_fully_qualified TSRMLS_CC);
if (zend_constant_ct_subst(result, &resolved_name, 1 TSRMLS_CC)) {
zval_dtor(&resolved_name);
if (zend_constant_ct_subst(&result->u.constant, resolved_name, 1 TSRMLS_CC)) {
result->op_type = IS_CONST;
zend_string_release(resolved_name);
return;
}
@ -5662,16 +5605,16 @@ void zend_compile_const(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
if (is_fully_qualified) {
opline->op2.constant = zend_add_const_name_literal(
CG(active_op_array), &resolved_name, 0 TSRMLS_CC);
CG(active_op_array), resolved_name, 0 TSRMLS_CC);
} else {
opline->extended_value = IS_CONSTANT_UNQUALIFIED;
if (CG(current_namespace)) {
opline->extended_value |= IS_CONSTANT_IN_NAMESPACE;
opline->op2.constant = zend_add_const_name_literal(
CG(active_op_array), &resolved_name, 1 TSRMLS_CC);
CG(active_op_array), resolved_name, 1 TSRMLS_CC);
} else {
opline->op2.constant = zend_add_const_name_literal(
CG(active_op_array), &resolved_name, 0 TSRMLS_CC);
CG(active_op_array), resolved_name, 0 TSRMLS_CC);
}
}
zend_alloc_cache_slot(opline->op2.constant TSRMLS_CC);
@ -5842,7 +5785,7 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr TSRMLS_DC) /* {{{ */
zend_ast *ast = *ast_ptr;
zend_ast *class_ast = ast->child[0];
zend_ast *const_ast = ast->child[1];
zend_string *class_name = zend_ast_get_str(class_ast);
zend_string *class_name;
zend_string *const_name = zend_ast_get_str(const_ast);
zval result;
int fetch_type;
@ -5852,6 +5795,7 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr TSRMLS_DC) /* {{{ */
"Dynamic class names are not allowed in compile-time class constant references");
}
class_name = zend_ast_get_str(class_ast);
fetch_type = zend_get_class_fetch_type(class_name);
if (ZEND_FETCH_CLASS_STATIC == fetch_type) {
@ -5882,20 +5826,19 @@ void zend_compile_const_expr_const(zend_ast **ast_ptr TSRMLS_DC) /* {{{ */
{
zend_ast *ast = *ast_ptr;
zend_ast *name_ast = ast->child[0];
zval *orig_name = zend_ast_get_zval(name_ast);
zend_string *orig_name = zend_ast_get_str(name_ast);
zend_bool is_fully_qualified;
znode result;
zval resolved_name;
zval result, resolved_name;
if (zend_constant_ct_subst(&result, orig_name, 0 TSRMLS_CC)) {
zend_ast_destroy(ast);
*ast_ptr = zend_ast_create_zval(&result.u.constant);
*ast_ptr = zend_ast_create_zval(&result);
return;
}
ZVAL_STR(&resolved_name, zend_resolve_const_name(
Z_STR_P(orig_name), name_ast->attr, &is_fully_qualified TSRMLS_CC));
orig_name, name_ast->attr, &is_fully_qualified TSRMLS_CC));
Z_TYPE_INFO(resolved_name) = IS_CONSTANT_EX;
if (!is_fully_qualified) {
@ -6377,16 +6320,11 @@ void zend_eval_const_expr(zend_ast **ast_ptr TSRMLS_DC) /* {{{ */
return;
}
break;
case ZEND_AST_CONST: {
znode result_node;
if (!zend_constant_ct_subst(&result_node, zend_ast_get_zval(ast->child[0]), 0 TSRMLS_CC)) {
case ZEND_AST_CONST:
if (!zend_constant_ct_subst(&result, zend_ast_get_str(ast->child[0]), 0 TSRMLS_CC)) {
return;
}
zend_ast_destroy(ast);
*ast_ptr = zend_ast_create_zval(&result_node.u.constant);
return;
}
break;
default:
return;
}

View File

@ -223,6 +223,9 @@ typedef struct _zend_try_catch_element {
/* op_array has finally blocks */
#define ZEND_ACC_HAS_FINALLY_BLOCK 0x20000000
/* internal function is allocated at arena */
#define ZEND_ACC_ARENA_ALLOCATED 0x20000000
#define ZEND_CE_IS_TRAIT(ce) (((ce)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT)
char *zend_visibility_string(uint32_t fn_flags);

View File

@ -100,15 +100,6 @@ static const zend_internal_function zend_pass_function = {
#define FREE_OP(should_free) \
if (should_free.var) { \
if ((zend_uintptr_t)should_free.var & 1L) { \
zval_dtor((zval*)((zend_uintptr_t)should_free.var & ~1L)); \
} else { \
zval_ptr_dtor_nogc(should_free.var); \
} \
}
#define FREE_OP_IF_VAR(should_free) \
if (should_free.var != NULL && (((zend_uintptr_t)should_free.var & 1L) == 0)) { \
zval_ptr_dtor_nogc(should_free.var); \
}
@ -117,10 +108,6 @@ static const zend_internal_function zend_pass_function = {
zval_ptr_dtor_nogc(should_free.var); \
}
#define TMP_FREE(z) (zval*)(((zend_uintptr_t)(z)) | 1L)
#define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L)
/* End of zend_execute_locks.h */
#define CV_DEF_OF(i) (EX(func)->op_array.vars[i])
@ -362,7 +349,7 @@ static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const zend_
break;
case IS_TMP_VAR:
ret = EX_VAR(node->var);
should_free->var = TMP_FREE(ret);
should_free->var = ret;
return ret;
break;
case IS_VAR:
@ -392,7 +379,7 @@ static inline zval *_get_zval_ptr_deref(int op_type, const znode_op *node, const
break;
case IS_TMP_VAR:
ret = EX_VAR(node->var);
should_free->var = TMP_FREE(ret);
should_free->var = ret;
return ret;
break;
case IS_VAR:
@ -744,10 +731,12 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p
ZVAL_COPY(retval, value);
}
zval_ptr_dtor(value);
FREE_OP_IF_VAR(free_value);
if (value_type == IS_VAR) {
FREE_OP(free_value);
}
}
static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, int value_type, zval *result TSRMLS_DC)
static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, zval *result TSRMLS_DC)
{
zend_string *old_str;
@ -779,12 +768,6 @@ static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *valu
zend_string_release(tmp);
} else {
Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0];
if (value_type == IS_TMP_VAR) {
/* we can safely free final_value here
* because separation is done only
* in case value_type == IS_VAR */
zval_dtor(value);
}
}
/*
* the value of an assignment to a string offset is undefined
@ -824,7 +807,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
return variable_ptr;
}
garbage = Z_COUNTED_P(variable_ptr);
if (GC_REFCOUNT(garbage) == 1) {
if (--GC_REFCOUNT(garbage) == 0) {
ZVAL_COPY_VALUE(variable_ptr, value);
if (value_type == IS_CONST) {
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
@ -836,10 +819,9 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
Z_ADDREF_P(variable_ptr);
}
}
_zval_dtor_func(garbage ZEND_FILE_LINE_CC);
_zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
return variable_ptr;
} else { /* we need to split */
GC_REFCOUNT(garbage)--;
/* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */
if ((Z_COLLECTABLE_P(variable_ptr)) &&
UNEXPECTED(!GC_INFO(garbage))) {
@ -1036,7 +1018,7 @@ fetch_from_array:
zend_long offset;
if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
zval_dtor(container);
zval_ptr_dtor_nogc(container);
convert_to_array:
ZVAL_NEW_ARR(container);
zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
@ -1337,13 +1319,9 @@ static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_of
if (nest_levels>1) {
zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_ptr_dtor(EX_VAR(brk_opline->op1.var));
}
} else if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_dtor(EX_VAR(brk_opline->op1.var));
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
}
}

View File

@ -57,19 +57,9 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
} else if (brk_cont->brk > op_num) {
zend_op *brk_opline = op_array->opcodes + brk_cont->brk;
switch (brk_opline->opcode) {
case ZEND_SWITCH_FREE:
{
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
zval_ptr_dtor(var);
}
break;
case ZEND_FREE:
{
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
zval_dtor(var);
}
break;
if (brk_opline->opcode == ZEND_FREE) {
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
zval_ptr_dtor_nogc(var);
}
}
}

View File

@ -119,8 +119,14 @@ static void do_inherit_parent_constructor(zend_class_entry *ce TSRMLS_DC) /* {{{
if ((function = zend_hash_str_find_ptr(&ce->parent->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1)) != NULL) {
/* inherit parent's constructor */
if (function->type == ZEND_INTERNAL_FUNCTION) {
new_function = pemalloc(sizeof(zend_internal_function), 1);
memcpy(new_function, function, sizeof(zend_internal_function));
if (ce->type & ZEND_INTERNAL_CLASS) {
new_function = pemalloc(sizeof(zend_internal_function), 1);
memcpy(new_function, function, sizeof(zend_internal_function));
} else {
new_function = zend_arena_alloc(&CG(arena), sizeof(zend_internal_function));
memcpy(new_function, function, sizeof(zend_internal_function));
new_function->common.fn_flags |= ZEND_ACC_ARENA_ALLOCATED;
}
} else {
new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
memcpy(new_function, function, sizeof(zend_op_array));
@ -141,8 +147,19 @@ static void do_inherit_parent_constructor(zend_class_entry *ce TSRMLS_DC) /* {{{
(function = zend_hash_find_ptr(&ce->parent->function_table, lc_parent_class_name)) != NULL) {
if (function->common.fn_flags & ZEND_ACC_CTOR) {
/* inherit parent's constructor */
new_function = pemalloc(sizeof(zend_function), function->type == ZEND_INTERNAL_FUNCTION);
memcpy(new_function, function, sizeof(zend_function));
if (function->type == ZEND_INTERNAL_FUNCTION) {
if (ce->type & ZEND_INTERNAL_CLASS) {
new_function = pemalloc(sizeof(zend_internal_function), 1);
memcpy(new_function, function, sizeof(zend_internal_function));
} else {
new_function = zend_arena_alloc(&CG(arena), sizeof(zend_internal_function));
memcpy(new_function, function, sizeof(zend_internal_function));
new_function->common.fn_flags |= ZEND_ACC_ARENA_ALLOCATED;
}
} else {
new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
memcpy(new_function, function, sizeof(zend_op_array));
}
zend_hash_update_ptr(&ce->function_table, lc_parent_class_name, new_function);
function_add_ref(new_function);
}
@ -170,13 +187,19 @@ char *zend_visibility_string(uint32_t fn_flags) /* {{{ */
}
/* }}} */
static zend_function *do_inherit_method(zend_function *old_function TSRMLS_DC) /* {{{ */
static zend_function *do_inherit_method(zend_function *old_function, zend_class_entry *ce TSRMLS_DC) /* {{{ */
{
zend_function *new_function;
if (old_function->type == ZEND_INTERNAL_FUNCTION) {
new_function = pemalloc(sizeof(zend_internal_function), 1);
memcpy(new_function, old_function, sizeof(zend_internal_function));
if (ce->type & ZEND_INTERNAL_CLASS) {
new_function = pemalloc(sizeof(zend_internal_function), 1);
memcpy(new_function, old_function, sizeof(zend_internal_function));
} else {
new_function = zend_arena_alloc(&CG(arena), sizeof(zend_internal_function));
memcpy(new_function, old_function, sizeof(zend_internal_function));
new_function->common.fn_flags |= ZEND_ACC_ARENA_ALLOCATED;
}
} else {
new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
memcpy(new_function, old_function, sizeof(zend_op_array));
@ -796,7 +819,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
ZEND_HASH_FOREACH_STR_KEY_PTR(&parent_ce->function_table, key, func) {
if (do_inherit_method_check(&ce->function_table, func, key, ce)) {
zend_function *new_func = do_inherit_method(func TSRMLS_CC);
zend_function *new_func = do_inherit_method(func, ce TSRMLS_CC);
zend_hash_add_new_ptr(&ce->function_table, key, new_func);
}
} ZEND_HASH_FOREACH_END();
@ -884,7 +907,7 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
ZEND_HASH_FOREACH_STR_KEY_PTR(&iface->function_table, key, func) {
if (do_inherit_method_check(&ce->function_table, func, key, ce)) {
zend_function *new_func = do_inherit_method(func TSRMLS_CC);
zend_function *new_func = do_inherit_method(func, ce TSRMLS_CC);
zend_hash_add_new_ptr(&ce->function_table, key, new_func);
}
} ZEND_HASH_FOREACH_END();

View File

@ -100,16 +100,12 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC)
{
switch (function->type) {
case ZEND_USER_FUNCTION:
destroy_op_array((zend_op_array *) function TSRMLS_CC);
break;
case ZEND_INTERNAL_FUNCTION:
if (function->common.function_name) {
zend_string_release(function->common.function_name);
}
/* do nothing */
break;
if (function->type == ZEND_USER_FUNCTION) {
destroy_op_array(&function->op_array TSRMLS_CC);
} else {
ZEND_ASSERT(function->type == ZEND_INTERNAL_FUNCTION);
ZEND_ASSERT(function->common.function_name);
zend_string_release(function->common.function_name);
}
}
@ -118,11 +114,18 @@ ZEND_API void zend_function_dtor(zval *zv)
zend_function *function = Z_PTR_P(zv);
TSRMLS_FETCH();
destroy_zend_function(function TSRMLS_CC);
if (function->type == ZEND_INTERNAL_FUNCTION) {
pefree(function, 1);
} else if (!function->common.function_name) {
efree_size(function, sizeof(zend_op_array));
if (function->type == ZEND_USER_FUNCTION) {
ZEND_ASSERT(function->common.function_name);
destroy_op_array(&function->op_array TSRMLS_CC);
/* op_arrays are allocated on arena, so we don't have to free them */
//??? efree_size(function, sizeof(zend_op_array));
} else {
ZEND_ASSERT(function->type == ZEND_INTERNAL_FUNCTION);
ZEND_ASSERT(function->common.function_name);
zend_string_release(function->common.function_name);
if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) {
pefree(function, 1);
}
}
}

View File

@ -827,8 +827,6 @@ try_again:
case IS_NULL:
case IS_FALSE:
return STR_EMPTY_ALLOC();
case IS_STRING:
return zend_string_copy(Z_STR_P(op));
case IS_TRUE:
return zend_string_init("1", 1, 0);
case IS_RESOURCE: {
@ -868,6 +866,8 @@ try_again:
case IS_REFERENCE:
op = Z_REFVAL_P(op);
goto try_again;
case IS_STRING:
return zend_string_copy(Z_STR_P(op));
EMPTY_SWITCH_DEFAULT_CASE()
}
return NULL;

View File

@ -285,7 +285,6 @@ ZEND_API int zend_atoi(const char *str, int str_len);
ZEND_API zend_long zend_atol(const char *str, int str_len);
ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC);
END_EXTERN_C()
#define convert_to_ex_master(pzv, lower_type, upper_type) \
if (Z_TYPE_P(pzv)!=upper_type) { \
@ -928,6 +927,8 @@ static zend_always_inline char *zend_print_long_to_buf(char *buf, zend_long num)
ZEND_API zend_string *zend_long_to_str(zend_long num);
END_EXTERN_C()
#endif
/*

View File

@ -1392,7 +1392,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HELPER(zend_fetch_property_address_read_helper, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
USE_OPLINE
zend_free_op free_op1;
@ -1425,11 +1425,6 @@ ZEND_VM_HELPER(zend_fetch_property_address_read_helper, CONST|TMP|VAR|UNUSED|CV,
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_property_address_read_helper);
}
ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
USE_OPLINE
@ -1540,7 +1535,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_property_address_read_helper);
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_R);
}
}
@ -1643,26 +1638,27 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
FREE_OP2();
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
if (UNEXPECTED(variable_ptr != NULL)) {
zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
}
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
FREE_OP_VAR_PTR(free_op_data2);
} else {
value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC);
if ((opline+1)->op1_type == IS_VAR) {
FREE_OP(free_op_data1);
}
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
FREE_OP_VAR_PTR(free_op_data2);
}
}
FREE_OP_IF_VAR(free_op_data1);
}
FREE_OP1_VAR_PTR();
/* assign_dim has two opcodes! */
@ -1684,7 +1680,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (OP2_TYPE == IS_TMP_VAR) {
zval_dtor(value);
FREE_OP2();
}
if (RETURN_VALUE_USED(opline)) {
ZVAL_NULL(EX_VAR(opline->result.var));
@ -2041,11 +2037,7 @@ ZEND_VM_HANDLER(70, ZEND_FREE, TMP|VAR, ANY)
USE_OPLINE
SAVE_OPLINE();
if (OP1_TYPE == IS_TMP_VAR) {
zval_dtor(EX_VAR(opline->op1.var));
} else {
zval_ptr_dtor(EX_VAR(opline->op1.var));
}
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@ -3652,13 +3644,9 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
brk_opline = EX(func)->op_array.opcodes + el->brk;
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_ptr_dtor(EX_VAR(brk_opline->op1.var));
}
} else if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_dtor(EX_VAR(brk_opline->op1.var));
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
}
ZEND_VM_JMP(opline->op1.jmp_addr);
@ -3680,16 +3668,6 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, VAR, ANY)
{
USE_OPLINE
SAVE_OPLINE();
zval_ptr_dtor(EX_VAR(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
{
USE_OPLINE
@ -4480,7 +4458,10 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
ZVAL_DEREF(array_ptr);
if (OP1_TYPE == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&tmp, array_ptr);
array_ptr = &tmp;
if (Z_OPT_IMMUTABLE_P(&tmp)) {
zval_copy_ctor_func(&tmp);
}
array_ref = array_ptr = &tmp;
if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
ce = Z_OBJCE_P(array_ptr);
if (ce && ce->get_iterator) {
@ -4496,10 +4477,11 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
}
} else if (Z_IMMUTABLE_P(array_ref)) {
if (OP1_TYPE == IS_CV) {
zval_copy_ctor(array_ref);
zval_copy_ctor_func(array_ref);
Z_ADDREF_P(array_ref);
} else {
ZVAL_DUP(&tmp, array_ref);
ZVAL_COPY_VALUE(&tmp, array_ref);
zval_copy_ctor_func(&tmp);
array_ptr = array_ref = &tmp;
}
} else if (Z_REFCOUNTED_P(array_ref)) {
@ -4520,14 +4502,13 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
ZVAL_UNREF(array_ref);
array_ptr = array_ref;
}
if (Z_IMMUTABLE_P(array_ptr) ||
(Z_ISREF_P(array_ref) &&
Z_REFCOUNTED_P(array_ptr) &&
Z_REFCOUNT_P(array_ptr) > 1)) {
if (!Z_IMMUTABLE_P(array_ptr)) {
Z_DELREF_P(array_ptr);
}
zval_copy_ctor(array_ptr);
if (Z_IMMUTABLE_P(array_ptr)) {
zval_copy_ctor_func(array_ptr);
} else if (Z_ISREF_P(array_ref) &&
Z_COPYABLE_P(array_ptr) &&
Z_REFCOUNT_P(array_ptr) > 1) {
Z_DELREF_P(array_ptr);
zval_copy_ctor_func(array_ptr);
}
if (OP1_TYPE == IS_CV) {
Z_ADDREF_P(array_ref);
@ -4644,7 +4625,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
array = Z_REFVAL_P(array);
// TODO: referenced value might be changed to different array ???
if (Z_IMMUTABLE_P(array)) {
zval_copy_ctor(array);
zval_copy_ctor_func(array);
}
}
@ -5485,13 +5466,9 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
catch_op_num >= EX(func)->op_array.brk_cont_array[i].brk) {
zend_op *brk_opline = &EX(func)->op_array.opcodes[EX(func)->op_array.brk_cont_array[i].brk];
if (brk_opline->opcode == ZEND_SWITCH_FREE) {
if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_ptr_dtor(EX_VAR(brk_opline->op1.var));
}
} else if (brk_opline->opcode == ZEND_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval_dtor(EX_VAR(brk_opline->op1.var));
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
}
}
}
@ -5687,7 +5664,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
/* Temporary variables don't need ctor copying */
if (OP1_TYPE != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
zval_opt_copy_ctor(&generator->value);
}
} else {
zval *value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);

File diff suppressed because it is too large Load Diff

View File

@ -245,7 +245,7 @@ $op2_get_obj_zval_ptr_ptr = array(
$op1_free_op = array(
"ANY" => "FREE_OP(free_op1)",
"TMP" => "zval_dtor(free_op1.var)",
"TMP" => "zval_ptr_dtor_nogc(free_op1.var)",
"VAR" => "zval_ptr_dtor_nogc(free_op1.var)",
"CONST" => "",
"UNUSED" => "",
@ -254,7 +254,7 @@ $op1_free_op = array(
$op2_free_op = array(
"ANY" => "FREE_OP(free_op2)",
"TMP" => "zval_dtor(free_op2.var)",
"TMP" => "zval_ptr_dtor_nogc(free_op2.var)",
"VAR" => "zval_ptr_dtor_nogc(free_op2.var)",
"CONST" => "",
"UNUSED" => "",
@ -262,7 +262,7 @@ $op2_free_op = array(
);
$op1_free_op_if_var = array(
"ANY" => "FREE_OP_IF_VAR(free_op1)",
"ANY" => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(free_op1.var);}",
"TMP" => "",
"VAR" => "zval_ptr_dtor_nogc(free_op1.var)",
"CONST" => "",
@ -271,7 +271,7 @@ $op1_free_op_if_var = array(
);
$op2_free_op_if_var = array(
"ANY" => "FREE_OP_IF_VAR(free_op2)",
"ANY" => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(free_op1.var);}",
"TMP" => "",
"VAR" => "zval_ptr_dtor_nogc(free_op2.var)",
"CONST" => "",

View File

@ -71,7 +71,7 @@ const char *zend_vm_opcodes_map[169] = {
"ZEND_JMPZ_EX",
"ZEND_JMPNZ_EX",
"ZEND_CASE",
"ZEND_SWITCH_FREE",
NULL,
"ZEND_BRK",
"ZEND_CONT",
"ZEND_BOOL",

View File

@ -72,7 +72,6 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
#define ZEND_JMPZ_EX 46
#define ZEND_JMPNZ_EX 47
#define ZEND_CASE 48
#define ZEND_SWITCH_FREE 49
#define ZEND_BRK 50
#define ZEND_CONT 51
#define ZEND_BOOL 52

View File

@ -203,14 +203,12 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz
j = 0;
for (i = 0; i< op_array->last_brk_cont; i++) {
if (op_array->brk_cont_array[i].start >= 0 &&
(op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE ||
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_SWITCH_FREE)) {
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE) {
int parent = op_array->brk_cont_array[i].parent;
while (parent >= 0 &&
op_array->brk_cont_array[parent].start < 0 &&
op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_FREE &&
op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_SWITCH_FREE) {
op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_FREE) {
parent = op_array->brk_cont_array[parent].parent;
}
op_array->brk_cont_array[i].parent = parent;
@ -224,8 +222,7 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz
j = 0;
for (i = 0; i< op_array->last_brk_cont; i++) {
if (op_array->brk_cont_array[i].start >= 0 &&
(op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE ||
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_SWITCH_FREE)) {
op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE) {
if (i != j) {
op_array->brk_cont_array[j] = op_array->brk_cont_array[i];
}
@ -1363,10 +1360,9 @@ static void zend_jmp_optimization(zend_code_block *block, zend_op_array *op_arra
} else if (0&& block->op1_to != block &&
block->op1_to != blocks &&
op_array->last_try_catch == 0 &&
target->opcode != ZEND_FREE &&
target->opcode != ZEND_SWITCH_FREE) {
target->opcode != ZEND_FREE) {
/* Block Reordering (saves one JMP on each "for" loop iteration)
* It is disabled for some cases (ZEND_FREE/ZEND_SWITCH_FREE)
* It is disabled for some cases (ZEND_FREE)
* which may break register allocation.
*/
zend_bool can_reorder = 0;

View File

@ -91,7 +91,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
zend_optimizer_replace_by_const(op_array, opline + 1, IS_TMP_VAR, tv, &result TSRMLS_CC);
}
break;
@ -101,6 +101,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
opline->extended_value != IS_OBJECT &&
opline->extended_value != IS_RESOURCE) {
/* cast of constant operand */
zend_uchar type = opline->result_type;
uint32_t tv = ZEND_RESULT(opline).var; /* temporary variable */
zval res;
res = ZEND_OP1_LITERAL(opline);
@ -126,11 +127,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
literal_dtor(&ZEND_OP1_LITERAL(opline));
MAKE_NOP(opline);
if (opline->result_type == IS_TMP_VAR) {
zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC);
} else /* if (opline->result_type == IS_VAR) */ {
zend_optimizer_replace_var_by_const(op_array, opline + 1, tv, &res TSRMLS_CC);
}
zend_optimizer_replace_by_const(op_array, opline + 1, type, tv, &res TSRMLS_CC);
} else if (opline->extended_value == _IS_BOOL) {
/* T = CAST(X, IS_BOOL) => T = BOOL(X) */
opline->opcode = ZEND_BOOL;
@ -157,7 +154,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
literal_dtor(&ZEND_OP1_LITERAL(opline));
MAKE_NOP(opline);
zend_optimizer_replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
zend_optimizer_replace_by_const(op_array, opline + 1, IS_TMP_VAR, tv, &result TSRMLS_CC);
}
break;
@ -251,7 +248,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
zend_optimizer_replace_tmp_by_const(op_array, opline, tv, offset TSRMLS_CC);
zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, offset TSRMLS_CC);
}
EG(current_execute_data) = orig_execute_data;
break;
@ -271,7 +268,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
}
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC);
zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, &c TSRMLS_CC);
}
/* class constant */
@ -332,7 +329,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
}
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &t TSRMLS_CC);
zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, &t TSRMLS_CC);
}
}
}
@ -388,7 +385,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
func->module->type == MODULE_PERSISTENT) {
zval t;
ZVAL_BOOL(&t, 1);
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@ -421,7 +418,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
}
}
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@ -436,7 +433,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 0 TSRMLS_CC)) {
ZVAL_BOOL(&t, 1);
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@ -450,7 +447,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
zval t;
if (zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline + 1)), &t, 1 TSRMLS_CC)) {
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@ -465,7 +462,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
zval t;
ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline + 1)));
if (zend_optimizer_replace_var_by_const(op_array, opline + 3, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
if (zend_optimizer_replace_by_const(op_array, opline + 3, IS_VAR, ZEND_RESULT(opline + 2).var, &t TSRMLS_CC)) {
literal_dtor(&ZEND_OP2_LITERAL(opline));
MAKE_NOP(opline);
literal_dtor(&ZEND_OP1_LITERAL(opline + 1));
@ -481,7 +478,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
zval t;
ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline)));
zend_optimizer_replace_tmp_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC);
zend_optimizer_replace_by_const(op_array, opline + 1, IS_TMP_VAR, ZEND_RESULT(opline).var, &t TSRMLS_CC);
literal_dtor(&ZEND_OP1_LITERAL(opline));
MAKE_NOP(opline);
}
@ -494,7 +491,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
break;
}
ZVAL_TRUE(&c);
zend_optimizer_replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC);
zend_optimizer_replace_by_const(op_array, opline, IS_TMP_VAR, tv, &c TSRMLS_CC);
literal_dtor(&ZEND_OP1_LITERAL(opline));
MAKE_NOP(opline);
}

View File

@ -205,8 +205,7 @@ void zend_optimizer_pass2(zend_op_array *op_array TSRMLS_DC)
array_offset = jmp_to->parent;
if (--nest_levels > 0) {
if (opline->opcode == ZEND_BRK &&
(op_array->opcodes[jmp_to->brk].opcode == ZEND_FREE ||
op_array->opcodes[jmp_to->brk].opcode == ZEND_SWITCH_FREE)) {
op_array->opcodes[jmp_to->brk].opcode == ZEND_FREE) {
dont_optimize = 1;
break;
}

View File

@ -262,15 +262,16 @@ check_numeric:
}
}
int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
zend_op *opline,
uint32_t var,
zval *val TSRMLS_DC)
int zend_optimizer_replace_by_const(zend_op_array *op_array,
zend_op *opline,
zend_uchar type,
uint32_t var,
zval *val TSRMLS_DC)
{
zend_op *end = op_array->opcodes + op_array->last;
while (opline < end) {
if (ZEND_OP1_TYPE(opline) == IS_VAR &&
if (ZEND_OP1_TYPE(opline) == type &&
ZEND_OP1(opline).var == var) {
switch (opline->opcode) {
case ZEND_FETCH_DIM_W:
@ -292,6 +293,25 @@ int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
opline->opcode = ZEND_SEND_VAL;
}
break;
/* In most cases IS_TMP_VAR operand may be used only once.
* The operands are usually destroyed by the opcode handler.
* ZEND_CASE is an exception, that keeps operand unchanged,
* and allows its reuse. The number of ZEND_CASE instructions
* usually terminated by ZEND_FREE that finally kills the value.
*/
case ZEND_CASE: {
zval old_val;
ZVAL_COPY_VALUE(&old_val, val);
zval_copy_ctor(val);
zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC);
zval_dtor(&old_val);
opline++;
continue;
}
case ZEND_FREE:
MAKE_NOP(opline);
zval_dtor(val);
return 1;
default:
break;
}
@ -299,7 +319,7 @@ int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
break;
}
if (ZEND_OP2_TYPE(opline) == IS_VAR &&
if (ZEND_OP2_TYPE(opline) == type &&
ZEND_OP2(opline).var == var) {
switch (opline->opcode) {
case ZEND_ASSIGN_REF:
@ -316,55 +336,6 @@ int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
return 1;
}
void zend_optimizer_replace_tmp_by_const(zend_op_array *op_array,
zend_op *opline,
uint32_t var,
zval *val
TSRMLS_DC)
{
zend_op *end = op_array->opcodes + op_array->last;
while (opline < end) {
if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
ZEND_OP1(opline).var == var) {
/* In most cases IS_TMP_VAR operand may be used only once.
* The operands are usually destroyed by the opcode handler.
* ZEND_CASE is an exception, that keeps operand unchanged,
* and allows its reuse. The number of ZEND_CASE instructions
* usually terminated by ZEND_FREE that finally kills the value.
*/
if (opline->opcode == ZEND_CASE) {
zval old_val;
ZVAL_COPY_VALUE(&old_val, val);
zval_copy_ctor(val);
zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC);
ZVAL_COPY_VALUE(val, &old_val);
} else if (opline->opcode == ZEND_FREE) {
MAKE_NOP(opline);
break;
} else {
zend_optimizer_update_op1_const(op_array, opline, val TSRMLS_CC);
val = NULL;
break;
}
}
if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
ZEND_OP2(opline).var == var) {
zend_optimizer_update_op2_const(op_array, opline, val TSRMLS_CC);
/* TMP_VAR may be used only once */
val = NULL;
break;
}
opline++;
}
if (val) {
zval_dtor(val);
}
}
static void zend_optimize(zend_op_array *op_array,
zend_optimizer_ctx *ctx TSRMLS_DC)
{

View File

@ -112,14 +112,11 @@ void zend_optimizer_update_op1_const(zend_op_array *op_array,
void zend_optimizer_update_op2_const(zend_op_array *op_array,
zend_op *opline,
zval *val TSRMLS_DC);
int zend_optimizer_replace_var_by_const(zend_op_array *op_array,
zend_op *opline,
uint32_t var,
zval *val TSRMLS_DC);
void zend_optimizer_replace_tmp_by_const(zend_op_array *op_array,
zend_op *opline,
uint32_t var,
zval *val TSRMLS_DC);
int zend_optimizer_replace_by_const(zend_op_array *op_array,
zend_op *opline,
zend_uchar type,
uint32_t var,
zval *val TSRMLS_DC);
void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS_DC);
void zend_optimizer_pass2(zend_op_array *op_array TSRMLS_DC);

View File

@ -384,6 +384,9 @@ static void accel_use_shm_interned_strings(TSRMLS_D)
if (p->key) {
p->key = accel_new_interned_string(p->key TSRMLS_CC);
}
if (Z_FUNC(p->val)->common.function_name) {
Z_FUNC(p->val)->common.function_name = accel_new_interned_string(Z_FUNC(p->val)->common.function_name TSRMLS_CC);
}
}
/* class table hash keys, class names, properties, methods, constants, etc */
@ -425,6 +428,9 @@ static void accel_use_shm_interned_strings(TSRMLS_D)
if (q->key) {
q->key = accel_new_interned_string(q->key TSRMLS_CC);
}
if (Z_FUNC(q->val)->common.function_name) {
Z_FUNC(q->val)->common.function_name = accel_new_interned_string(Z_FUNC(q->val)->common.function_name TSRMLS_CC);
}
}
for (j = 0; j < ce->constants_table.nNumUsed; j++) {

View File

@ -75,7 +75,7 @@ zend_persistent_script* create_persistent_script(void)
zend_persistent_script *persistent_script = (zend_persistent_script *) emalloc(sizeof(zend_persistent_script));
memset(persistent_script, 0, sizeof(zend_persistent_script));
zend_hash_init(&persistent_script->function_table, 128, NULL, (dtor_func_t) zend_accel_destroy_zend_function, 0);
zend_hash_init(&persistent_script->function_table, 128, NULL, ZEND_FUNCTION_DTOR, 0);
/* class_table is usually destroyed by free_persistent_script() that
* overrides destructor. ZEND_CLASS_DTOR may be used by standard
* PHP compiler

View File

@ -8,6 +8,9 @@ PHP_ARG_WITH(openssl, for OpenSSL support,
PHP_ARG_WITH(kerberos, for Kerberos support,
[ --with-kerberos[=DIR] OPENSSL: Include Kerberos support], no, no)
PHP_ARG_WITH(system-ciphers, whether to use system default cipher list instead of hardcoded value,
[ --with-system-ciphers OPENSSL: Use system default cipher list instead of hardcoded value], no, no)
if test "$PHP_OPENSSL" != "no"; then
PHP_NEW_EXTENSION(openssl, openssl.c xp_ssl.c, $ext_shared)
PHP_SUBST(OPENSSL_SHARED_LIBADD)
@ -25,4 +28,7 @@ if test "$PHP_OPENSSL" != "no"; then
], [
AC_MSG_ERROR([OpenSSL check failed. Please check config.log for more information.])
])
if test "$PHP_SYSTEM_CIPHERS" != "no"; then
AC_DEFINE(USE_OPENSSL_SYSTEM_CIPHERS,1,[ Use system default cipher list instead of hardcoded value ])
fi
fi

View File

@ -1,28 +1,28 @@
-----BEGIN CERTIFICATE-----
MIICCTCCAXICCQDNMI29sowT7TANBgkqhkiG9w0BAQUFADBJMQswCQYDVQQGEwJT
MIICCTCCAXICCQCx2JwIhbRefzANBgkqhkiG9w0BAQUFADBJMQswCQYDVQQGEwJT
RzESMBAGA1UECBMJVGVzdHZpbGxlMREwDwYDVQQKEwhkYXRpYmJhdzETMBEGA1UE
AxQKKi50ZXN0LmNvbTAeFw0xMzA5MjEwNzUyMjRaFw0xNDA5MjEwNzUyMjRaMEkx
AxQKKi50ZXN0LmNvbTAeFw0xNDA5MjQxMTMzNTRaFw0yNDA5MjExMTMzNTRaMEkx
CzAJBgNVBAYTAlNHMRIwEAYDVQQIEwlUZXN0dmlsbGUxETAPBgNVBAoTCGRhdGli
YmF3MRMwEQYDVQQDFAoqLnRlc3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQCdzVnic8K5W4SVbwVuqezcTjeqVLoQ91vVNZB0Jnsuz6q3DoK03oAd1jTe
Vd0k+MQDbXpHoc37lA4+8z/g5Bs0UXxNx+nkbFTE7Ba2/G24caI9/cOXZPG3UViD
rtqXKL6h5/umqRG9Dt5liF2MVP9XFAesVC7B8+Ca+PbPlQoYzwIDAQABMA0GCSqG
SIb3DQEBBQUAA4GBAAS07u/Ke+EhEHidz6CG3Qcr+zg483JKRgZFyGz+YUKyyKKy
fmLs7JieGJxYQjOmIpj/6X9Gnb2HjIPDnI6A+MV1emXDTnnmsgf2/lZGcthhpZn2
rMbj9bI0iH6HwOVGtp4ZJA5fB7nj3J+gWNTCQzDDOxwX36d2LL9ua+UMnk/g
iQKBgQDBnR8DYzsN90kISI87kBvw40TQknS7/fuymWCmSrtRQLED8p2QL8PiYCZ8
UdcFVsv+di7MJvUOzW6dRo2DCu8Rojx3ML8dAtPsQkDdaCXDnOvCTQCAqFmxa1A9
c5kp0hbzCrucKGckb355A4NumFgX1fjQ705MfjGPgQef1ZtozQIDAQABMA0GCSqG
SIb3DQEBBQUAA4GBAGP07nJo0pI4FdsXuAHWr97XxV4EhHopFMw6svOZ3UtsRzmW
ScmmMdgd3c8ciVxOsztgnzvFq/nrUkw/3n/Xz/gtE7kZt9aS18SnCyyHPJcXmmUE
NsbyZ/7srIqCSrxUkP+N//nToqHxg1pqA/A8RzOOQUAp+UIVF6Zl/kkFNgt8
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCdzVnic8K5W4SVbwVuqezcTjeqVLoQ91vVNZB0Jnsuz6q3DoK0
3oAd1jTeVd0k+MQDbXpHoc37lA4+8z/g5Bs0UXxNx+nkbFTE7Ba2/G24caI9/cOX
ZPG3UViDrtqXKL6h5/umqRG9Dt5liF2MVP9XFAesVC7B8+Ca+PbPlQoYzwIDAQAB
AoGAeyzTwKPDl5QMRejHQL57GOwlH1vLcXrjv+VzwHZZKQ0IoKM++5fCQYf29KXp
XPahaluGW2u9sWa8R/7wGcd0Q4RtquGzsgT3+AQsIc5KfIamyOyDaRVM/ymX3fWg
gHIU7OOzB+ihOU8sHyRIwfbk01/kmrBXLRj8E31sy3i3PIECQQDQQYE+aN7Acrdt
yN5CaqvbkiCGjRvASlemiTzPosgOtndyp21w1gakJwKYhYDk1N6A6Qb8REMZqM/U
wFypldV/AkEAwfq6NFuhpGL6hDA7MvlyY1KiZ0cHetPUX+PgdNqy2DA+1Sv4i7gm
Wd/uA651K7aPXuUaf9dKtPCmZwI4M6SEsQJBALW89HTqP7niYoDEEnITdPaghxHk
gptERUln6lGo1L1CLus3gSI/JHyMLo+7scgAnEwTD62GRKhX0Ubwt+ymfTECQAY5
fHYnppU20+EgBxZIqOIFCc8UmWnYmE0Ha/Fz/x8u1SVUBuK84wYpSGL32yyu7ATY
hzQo/W229zABAzqtAdECQQCUdB7IBFpPnsfv/EUBFX7X/7zAc9JpACmu9It5ju8C
KIsMuz/02D+TQoJNjdAngBM+4AJDIaGFgTMIfaDMh5L7
MIICXgIBAAKBgQDBnR8DYzsN90kISI87kBvw40TQknS7/fuymWCmSrtRQLED8p2Q
L8PiYCZ8UdcFVsv+di7MJvUOzW6dRo2DCu8Rojx3ML8dAtPsQkDdaCXDnOvCTQCA
qFmxa1A9c5kp0hbzCrucKGckb355A4NumFgX1fjQ705MfjGPgQef1ZtozQIDAQAB
AoGADAnkAsbpxh2JKf2xAkgcpKbNAZcJsSLCwsEstEpTSWMXXqJ4T53YtTu7SOGh
2BAkkQbyM/l8JVZ6uUbIx8wnPzqAuB2hEDQHKZVyftDyJh+54Uyz0xV0JdWGWrFh
A+uDt/Zncx2g+qlkQG5J5nHnrd9OAns89wJXpBWA6twlsuECQQD/HC4wxOJzh1XI
YSWHWQulOnlNgZ2zERfmJeRfJ0ncmDOV2ofxOFQ+dMJ36XghPaH52KdxqWI1yQaE
yesx8ygFAkEAwkoF4lBuYdsXucJNDYf8o9MlBvazoriH0y26B/YozJ7iAEFqVvcC
TN+iKDIyiRALwR6a3nzhyFYJ4xyzgSIAKQJBAMnw3seQMsnM6aTS8cgwPr2uifNG
lTT4ZPi0KhEAosFSYhNPh6j1NAq0lnQhhgyaIywJypJ4yNtWpChdRiamGpkCQQDB
iUExPpOmMLwCk7VzrCmS+6pftHIevpi2WU99zMy5f+969665MFb/QqniRpamh/Bd
kGIPDPFQQbyZmqaJFNh5AkEAzy0YVbUT3C/QvstPr5i7ztj7WiW/1zJMamFwY/ZS
1J7e7lqHgRICie5uv1Yvh3w/qmV/7lTLhmlQZd9SJMpXhg==
-----END RSA PRIVATE KEY-----

View File

@ -1453,13 +1453,16 @@ int php_openssl_setup_crypto(php_stream *stream,
}
GET_VER_OPT_STRING("ciphers", cipherlist);
#ifndef USE_OPENSSL_SYSTEM_CIPHERS
if (!cipherlist) {
cipherlist = OPENSSL_DEFAULT_STREAM_CIPHERS;
}
if (SSL_CTX_set_cipher_list(sslsock->ctx, cipherlist) != 1) {
return FAILURE;
#endif
if (cipherlist) {
if (SSL_CTX_set_cipher_list(sslsock->ctx, cipherlist) != 1) {
return FAILURE;
}
}
if (FAILURE == set_local_cert(sslsock->ctx, stream TSRMLS_CC)) {
return FAILURE;
}

View File

@ -0,0 +1,14 @@
--TEST--
References are not counted twice
--FILE--
<?php
$ref1 = 1;
$ref2 = 2;
$arr = [&$ref1, &$ref1, &$ref2, &$ref2];
var_dump(serialize($arr));
?>
--EXPECT--
string(38) "a:4:{i:0;i:1;i:1;R:2;i:2;i:2;i:3;R:3;}"

View File

@ -604,15 +604,16 @@ static inline uint32_t php_add_var_hash(php_serialize_data_t data, zval *var TSR
{
zval *zv;
zend_ulong key;
zend_bool is_ref = Z_ISREF_P(var);
data->n += 1;
if (Z_TYPE_P(var) != IS_OBJECT && Z_TYPE_P(var) != IS_REFERENCE) {
if (!is_ref && Z_TYPE_P(var) != IS_OBJECT) {
return 0;
}
/* References to objects are treated as if the reference didn't exist */
if (Z_TYPE_P(var) == IS_REFERENCE && Z_TYPE_P(Z_REFVAL_P(var)) == IS_OBJECT) {
if (is_ref && Z_TYPE_P(Z_REFVAL_P(var)) == IS_OBJECT) {
var = Z_REFVAL_P(var);
}
@ -622,6 +623,11 @@ static inline uint32_t php_add_var_hash(php_serialize_data_t data, zval *var TSR
zv = zend_hash_index_find(&data->ht, key);
if (zv) {
/* References are only counted once, undo the data->n increment above */
if (is_ref) {
data->n -= 1;
}
return Z_LVAL_P(zv);
} else {
zval zv_n;

View File

@ -1758,7 +1758,7 @@ mssql.secure_connection = Off
;mbstring.encoding_translation = Off
; automatic encoding detection order.
; "auto" detect order is changed accoding to mbstring.language
; "auto" detect order is changed according to mbstring.language
; http://php.net/mbstring.detect-order
;mbstring.detect_order = auto

View File

@ -1756,7 +1756,7 @@ mssql.secure_connection = Off
;mbstring.encoding_translation = Off
; automatic encoding detection order.
; "auto" detect order is changed accoding to mbstring.language
; "auto" detect order is changed according to mbstring.language
; http://php.net/mbstring.detect-order
;mbstring.detect_order = auto

View File

@ -232,7 +232,6 @@ const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */
CASE(ZEND_JMPZ_EX);
CASE(ZEND_JMPNZ_EX);
CASE(ZEND_CASE);
CASE(ZEND_SWITCH_FREE);
CASE(ZEND_BRK);
CASE(ZEND_CONT);
CASE(ZEND_BOOL);