1
0
mirror of https://github.com/php/php-src.git synced 2026-04-28 18:53:33 +02:00

Merge branch 'master' of git.php.net:php-src

This commit is contained in:
George Wang
2015-12-17 15:25:39 -05:00
106 changed files with 10815 additions and 981 deletions
-4
View File
@@ -245,10 +245,6 @@ ext/reflection/spl.chm
ext/simplexml/examples/security.new.xml
ext/spl/examples/.htaccess
ext/spl/examples/*.phps
ext/sqlite/weztest.sqlite
ext/sqlite/libsqlite/src/sqlite.h
ext/sqlite/libsqlite/src/parse.out
ext/sqlite/libsqlite/src/libsqlite.dsw
ext/sqlite3/tests/phpsql*
ext/sqlite3/tests/*.db
ext/sqlite3/tests/*.tmp
+15 -4
View File
@@ -2,19 +2,30 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2016, PHP 7.1.0
Core:
- Core:
. Fixed bug #62210 (Exceptions can leak temporary variables). (Dmitry, Bob)
. Implemented the RFC `Support Class Constant Visibility`. (Sean DuBois,
Reeze Xia, Dmitry)
. Added void return type. (Andrea)
Hash:
- FTP:
. Implemented FR #55651 (Option to ignore the returned FTP PASV address).
(abrender at elitehosts dot com)
- Hash:
. Added SHA3 fixed mode algorithms (224, 256, 384, and 512 bit). (Sara)
PDO_Firebird:
- PDO_Firebird:
. Fixed bug #60052 (Integer returned as a 64bit integer on X64_86). (Mariuz)
Standard:
- Pgsql:
. Implemented FR #31021 (pg_result_notice() is needed to get all notice
messages). (Yasuo)
. Implemented FR #48532 (Allow pg_fetch_all() to index numerically). (Yasuo)
- Standard:
. Fixed bug #71100 (long2ip() doesn't accept integers in strict mode).
(Laruence)
. Implemented FR #55716 (Add an option to pass a custom stream context to
get_headers()). (Ferenc)
. Implemented FR #69359 (Provide a way to fetch the current environment
+7
View File
@@ -45,6 +45,13 @@ PHP 7.1 UPGRADE NOTES
- The first $varname argument for getenv() is no longer mandatory, the
current environment variables will be returned as an associative array
when omitted.
- long2ip() accepts integer as parameter now
- pg_last_notice() accepts optional 2nd bool parameter to get all notices and
returns empty string or array on successful calls. It returned FALSE for
empty notice previously.
- pg_fetch_all() accepts optional 2nd bool parameter to get numerically indexed
rows.
- pg_select() accepts PGSQL_FETCH_NUM option to get numerically indexed rows.
========================================
6. New Functions
@@ -0,0 +1,19 @@
--TEST--
Array addition is not commutative -- do not swap operands
--FILE--
<?php
$array = [1, 2, 3];
$array = [4, 5, 6] + $array;
var_dump($array);
?>
--EXPECT--
array(3) {
[0]=>
int(4)
[1]=>
int(5)
[2]=>
int(6)
}
+1 -1
View File
@@ -12,7 +12,7 @@ var_dump(parse_ini_file($ini_file));
?>
--CLEAN--
<?php
unlink(__DIR__ . "bug70748.ini");
unlink(__DIR__ . "/bug70748.ini");
?>
--EXPECTF--
Warning: syntax error, unexpected $end, expecting '}' in %sbug70748.ini on line %d
+31
View File
@@ -0,0 +1,31 @@
--TEST--
Bug #71067 (Local object in class method stays in memory for each call)
--INI--
opcache.enable=0
error_reporting=0
--FILE--
<?php
class Test {
public function test(){
$arr = (object) [
'children' => []
];
$arr->children[] = 1;
return $arr;
}
}
$o = new Test();
$o->test();
print_r($o->test());
?>
--EXPECT--
stdClass Object
(
[children] => Array
(
[0] => 1
)
)
+14
View File
@@ -0,0 +1,14 @@
--TEST--
Bug #71086: Invalid numeric literal parse error within highlight_string() function
--FILE--
<?php
$highlightedString = highlight_string("<?php \n 09 09 09;", true);
var_dump($highlightedString);
?>
--EXPECT--
string(169) "<code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php&nbsp;<br />&nbsp;</span><span style="color: #007700">09&nbsp;09&nbsp;09;</span>
</span>
</code>"
@@ -0,0 +1,22 @@
--TEST--
Global variable import using a name with side effects
--FILE--
<?php
function sf($arg) {
echo "called\n";
return $arg;
}
function test() {
global ${sf("a")};
var_dump($a);
}
$a = 42;
test();
?>
--EXPECT--
called
int(42)
+43
View File
@@ -0,0 +1,43 @@
--TEST--
Using an integer as a static property name
--FILE--
<?php
class Foo {
public static $bar = 42;
}
$n = 42;
${42} = 24;
var_dump(${42});
var_dump(${(int) 42});
var_dump(${(int) $n});
try {
var_dump(Foo::${42});
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(Foo::${(int) 42});
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump(Foo::${(int) $n});
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
int(24)
int(24)
int(24)
Access to undeclared static property: Foo::$42
Access to undeclared static property: Foo::$42
Access to undeclared static property: Foo::$42
+23
View File
@@ -0,0 +1,23 @@
--TEST--
return type with finally
--INI--
opcache.enable=0
--FILE--
<?php
function foo() : array {
try {
throw new Exception("xxxx");
} finally {
return ;
}
}
foo();
?>
--EXPECTF--
Fatal error: Uncaught TypeError: Return value of foo() must be of the type array, none returned in %s29.php:%d
Stack trace:
#0 %s(%d): foo()
#1 {main}
thrown in %s029.php on line %d
+23
View File
@@ -0,0 +1,23 @@
--TEST--
Bug #71092 (Segmentation fault with return type hinting)
--INI--
opcache.enable=0
--FILE--
<?php
function boom(): array {
$data = [['id']];
switch ($data[0]) {
case ['id']:
return;
}
}
boom();
?>
--EXPECTF--
Fatal error: Uncaught TypeError: Return value of boom() must be of the type array, none returned in %sbug71092.php:%d
Stack trace:
#0 %s(%d): boom()
#1 {main}
thrown in %sbug71092.php on line %d
@@ -0,0 +1,17 @@
--TEST--
instanceof self outside a class
--FILE--
<?php
$fn = function() {
try {
new stdClass instanceof self;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
};
$fn();
?>
--EXPECT--
Cannot access self:: when no class scope is active
@@ -0,0 +1,36 @@
--TEST--
Accessing self:: properties or methods outside a class
--FILE--
<?php
$fn = function() {
$str = "foo";
try {
self::${$str . "bar"};
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
unset(self::${$str . "bar"});
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
isset(self::${$str . "bar"});
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
self::{$str . "bar"}();
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
};
$fn();
?>
--EXPECT--
Cannot access self:: when no class scope is active
Cannot access self:: when no class scope is active
Cannot access self:: when no class scope is active
Cannot access self:: when no class scope is active
+1 -1
View File
@@ -622,7 +622,7 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
zval globals;
ZVAL_ARR(&globals, &EG(symbol_table));
Z_TYPE_INFO_P(&globals) = IS_ARRAY | (IS_TYPE_SYMBOLTABLE << Z_TYPE_FLAGS_SHIFT);
Z_TYPE_INFO_P(&globals) = IS_ARRAY;
ZVAL_NEW_REF(&globals, &globals);
zend_hash_update(&EG(symbol_table), name, &globals);
return 0;
+10 -4
View File
@@ -25,6 +25,7 @@
#include "zend_execute.h"
#include "zend_API.h"
#include "zend_modules.h"
#include "zend_extensions.h"
#include "zend_constants.h"
#include "zend_exceptions.h"
#include "zend_closures.h"
@@ -2004,7 +2005,7 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) /
lcname = zend_string_alloc(name_len, 0);
zend_str_tolower_copy(ZSTR_VAL(lcname), dep->name, name_len);
if (zend_hash_exists(&module_registry, lcname)) {
if (zend_hash_exists(&module_registry, lcname) || zend_get_extension(dep->name)) {
zend_string_free(lcname);
/* TODO: Check version relationship */
zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name);
@@ -3749,7 +3750,7 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n
}
if (zend_string_equals_literal_ci(name, "class")) {
zend_error((ce->type == ZEND_INTERNAL_CLASS) ? E_CORE_ERROR : E_COMPILE_ERROR,
zend_error_noreturn(ce->type == ZEND_INTERNAL_CLASS ? E_CORE_ERROR : E_COMPILE_ERROR,
"A class constant must not be called 'class'; it is reserved for class name fetching");
}
@@ -3765,8 +3766,13 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n
if (Z_CONSTANT_P(value)) {
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
}
return zend_hash_add_ptr(&ce->constants_table, name, c) ?
SUCCESS : FAILURE;
if (!zend_hash_add_ptr(&ce->constants_table, name, c)) {
zend_error_noreturn(ce->type == ZEND_INTERNAL_CLASS ? E_CORE_ERROR : E_COMPILE_ERROR,
"Cannot redefine class constant %s::%s", ZSTR_VAL(ce->name), ZSTR_VAL(name));
}
return SUCCESS;
}
/* }}} */
+2 -2
View File
@@ -2028,14 +2028,14 @@ ZEND_FUNCTION(zend_test_func)
{
zval *arg1, *arg2;
zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2);
zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2);
}
ZEND_FUNCTION(zend_test_func2)
{
zval *arg1, *arg2;
zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2);
zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2);
}
+24 -24
View File
@@ -1860,7 +1860,6 @@ static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */
case BP_VAR_R:
return;
case BP_VAR_W:
case BP_VAR_REF:
opline->opcode += 1 * factor;
return;
case BP_VAR_RW:
@@ -2616,6 +2615,7 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t
opline = zend_emit_op(result, ZEND_FETCH_STATIC_PROP_R, &prop_node, NULL);
}
if (opline->op1_type == IS_CONST) {
convert_to_string(CT_CONSTANT(opline->op1));
zend_alloc_polymorphic_cache_slot(opline->op1.constant);
}
if (class_node.op_type == IS_CONST) {
@@ -2625,7 +2625,6 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t
} else {
SET_NODE(opline->op2, &class_node);
}
opline->extended_value |= ZEND_FETCH_STATIC_MEMBER;
return opline;
}
@@ -2830,7 +2829,7 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
zend_ensure_writable_variable(target_ast);
zend_compile_var(&target_node, target_ast, BP_VAR_W);
zend_compile_var(&source_node, source_ast, BP_VAR_REF);
zend_compile_var(&source_node, source_ast, BP_VAR_W);
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");
@@ -2903,7 +2902,6 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */
{
/* TODO.AST &var error */
zend_ast_list *args = zend_ast_get_list(ast);
uint32_t i;
zend_bool uses_arg_unpack = 0;
@@ -3361,7 +3359,9 @@ static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string *
zend_compile_call_common(result, (zend_ast*)args, fbc);
CG(active_op_array)->opcodes[check_op_number].op2.opline_num = get_next_op_number(CG(active_op_array));
opline = &CG(active_op_array)->opcodes[check_op_number];
opline->op2.opline_num = get_next_op_number(CG(active_op_array));
SET_NODE(opline->result, result);
} else {
if (!fbc) {
zend_string_release(name);
@@ -3622,7 +3622,7 @@ void zend_compile_clone(znode *result, zend_ast *ast) /* {{{ */
znode obj_node;
zend_compile_expr(&obj_node, obj_ast);
zend_emit_op(result, ZEND_CLONE, &obj_node, NULL);
zend_emit_op_tmp(result, ZEND_CLONE, &obj_node, NULL);
}
/* }}} */
@@ -3642,12 +3642,16 @@ void zend_compile_global_var(zend_ast *ast) /* {{{ */
zend_op *opline = zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node);
zend_alloc_cache_slot(opline->op2.constant);
} else {
zend_emit_op(&result, ZEND_FETCH_W, &name_node, NULL);
/* name_ast should be evaluated only. FETCH_GLOBAL_LOCK instructs FETCH_W
* to not free the name_node operand, so it can be reused in the following
* ASSIGN_REF, which then frees it. */
zend_op *opline = zend_emit_op(&result, ZEND_FETCH_W, &name_node, NULL);
opline->extended_value = ZEND_FETCH_GLOBAL_LOCK;
// TODO.AST Avoid double fetch
//opline->extended_value = ZEND_FETCH_GLOBAL_LOCK;
zend_emit_assign_ref_znode(var_ast, &result);
zend_emit_assign_ref_znode(
zend_ast_create(ZEND_AST_VAR, zend_ast_create_znode(&name_node)),
&result
);
}
}
/* }}} */
@@ -3802,13 +3806,11 @@ void zend_compile_return(zend_ast *ast) /* {{{ */
expr_node.op_type = IS_CONST;
ZVAL_NULL(&expr_node.u.constant);
} else if (by_ref && zend_is_variable(expr_ast) && !zend_is_call(expr_ast)) {
zend_compile_var(&expr_node, expr_ast, BP_VAR_REF);
zend_compile_var(&expr_node, expr_ast, BP_VAR_W);
} else {
zend_compile_expr(&expr_node, expr_ast);
}
zend_handle_loops_and_finally();
if (CG(context).in_finally) {
opline = zend_emit_op(NULL, ZEND_DISCARD_EXCEPTION, NULL, NULL);
opline->op1_type = IS_TMP_VAR;
@@ -3819,6 +3821,9 @@ void zend_compile_return(zend_ast *ast) /* {{{ */
if (!(CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) && CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
zend_emit_return_type_check(expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1);
}
zend_handle_loops_and_finally();
opline = zend_emit_op(NULL, by_ref ? ZEND_RETURN_BY_REF : ZEND_RETURN,
&expr_node, NULL);
@@ -5228,10 +5233,7 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
zend_const_expr_to_zval(&value_zv, value_ast);
name = zend_new_interned_string_safe(name);
if (zend_declare_class_constant_ex(ce, name, &value_zv, ast->attr, doc_comment) != SUCCESS) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s",
ZSTR_VAL(ce->name), ZSTR_VAL(name));
}
zend_declare_class_constant_ex(ce, name, &value_zv, ast->attr, doc_comment);
}
}
/* }}} */
@@ -5488,7 +5490,6 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
opline = get_next_op(CG(active_op_array));
zend_make_var_result(&declare_node, opline);
// TODO.AST drop this
GET_NODE(&FC(implementing_class), opline->result);
opline->op2_type = IS_CONST;
@@ -6503,7 +6504,7 @@ void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
if (value_ast) {
if (returns_by_ref && zend_is_variable(value_ast) && !zend_is_call(value_ast)) {
zend_compile_var(&value_node, value_ast, BP_VAR_REF);
zend_compile_var(&value_node, value_ast, BP_VAR_W);
} else {
zend_compile_expr(&value_node, value_ast);
}
@@ -6544,7 +6545,8 @@ void zend_compile_instanceof(znode *result, zend_ast *ast) /* {{{ */
"instanceof expects an object instance, constant given");
}
zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_NO_AUTOLOAD);
zend_compile_class_ref_ex(&class_node, class_ast,
ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_EXCEPTION);
opline = zend_emit_op_tmp(result, ZEND_INSTANCEOF, &obj_node, NULL);
@@ -7468,9 +7470,7 @@ void zend_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
*result = *zend_ast_get_znode(ast);
return;
default:
if (type == BP_VAR_W || type == BP_VAR_REF
|| type == BP_VAR_RW || type == BP_VAR_UNSET
) {
if (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) {
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot use temporary expression in write context");
}
-2
View File
@@ -860,7 +860,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
#define BP_VAR_IS 3
#define BP_VAR_FUNC_ARG 4
#define BP_VAR_UNSET 5
#define BP_VAR_REF 6 /* right-hand side of by-ref assignment */
/* Bottom 3 bits are the type, top bits are arg num for BP_VAR_FUNC_ARG */
#define BP_VAR_SHIFT 3
@@ -892,7 +891,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
#define ZEND_FETCH_GLOBAL 0x00000000
#define ZEND_FETCH_LOCAL 0x10000000
#define ZEND_FETCH_STATIC 0x20000000
#define ZEND_FETCH_STATIC_MEMBER 0x30000000
#define ZEND_FETCH_GLOBAL_LOCK 0x40000000
#define ZEND_FETCH_LEXICAL 0x50000000
+8 -2
View File
@@ -150,7 +150,7 @@ static const zend_internal_function zend_pass_function = {
static zend_always_inline zend_vm_stack zend_vm_stack_new_page(size_t size, zend_vm_stack prev) {
zend_vm_stack page = (zend_vm_stack)emalloc(size);
page->top = ZEND_VM_STACK_ELEMETS(page);
page->top = ZEND_VM_STACK_ELEMENTS(page);
page->end = (zval*)((char*)page + size);
page->prev = prev;
return page;
@@ -1980,6 +1980,12 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
return;
}
} else if (EXPECTED(zobj->properties != NULL)) {
if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
GC_REFCOUNT(zobj->properties)--;
}
zobj->properties = zend_array_dup(zobj->properties);
}
retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr));
if (EXPECTED(retval)) {
ZVAL_INDIRECT(result, retval);
@@ -2413,7 +2419,7 @@ static zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call,
EG(vm_stack)->prev->top = (zval*)call;
/* delete previous stack segment if it becames empty */
if (UNEXPECTED(EG(vm_stack)->prev->top == ZEND_VM_STACK_ELEMETS(EG(vm_stack)->prev))) {
if (UNEXPECTED(EG(vm_stack)->prev->top == ZEND_VM_STACK_ELEMENTS(EG(vm_stack)->prev))) {
zend_vm_stack r = EG(vm_stack)->prev;
EG(vm_stack)->prev = r->prev;
+1 -1
View File
@@ -145,7 +145,7 @@ struct _zend_vm_stack {
#define ZEND_VM_STACK_HEADER_SLOTS \
((ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval)))
#define ZEND_VM_STACK_ELEMETS(stack) \
#define ZEND_VM_STACK_ELEMENTS(stack) \
(((zval*)(stack)) + ZEND_VM_STACK_HEADER_SLOTS)
/*
+1 -1
View File
@@ -218,7 +218,7 @@ static void zend_throw_or_error(int fetch_type, zend_class_entry *exception_ce,
zend_vspprintf(&message, 0, format, va);
if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) {
zend_throw_error(exception_ce, message);
zend_throw_error(exception_ce, "%s", message);
} else {
zend_error(E_ERROR, "%s", message);
}
+8
View File
@@ -109,6 +109,14 @@ int zend_load_extension(const char *path)
/* See http://support.microsoft.com/kb/190351 */
#ifdef ZEND_WIN32
fflush(stderr);
#endif
DL_UNLOAD(handle);
return FAILURE;
} else if (zend_get_extension(new_extension->name)) {
fprintf(stderr, "Cannot load %s - extension already loaded\n", new_extension->name);
/* See http://support.microsoft.com/kb/190351 */
#ifdef PHP_WIN32
fflush(stderr);
#endif
DL_UNLOAD(handle);
return FAILURE;
+4
View File
@@ -25,6 +25,7 @@
#include "zend_highlight.h"
#include "zend_ptr_stack.h"
#include "zend_globals.h"
#include "zend_exceptions.h"
ZEND_API void zend_html_putc(char c)
{
@@ -168,6 +169,9 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
}
zend_printf("</span>\n");
zend_printf("</code>");
/* Discard parse errors thrown during tokenization */
zend_clear_exception();
}
ZEND_API void zend_strip(void)
+6
View File
@@ -687,7 +687,13 @@ ZEND_API int pass_two(zend_op_array *op_array)
case ZEND_NEW:
case ZEND_FE_RESET_R:
case ZEND_FE_RESET_RW:
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
break;
case ZEND_ASSERT_CHECK:
/* If result of assert is unused, result of check is unused as well */
if (op_array->opcodes[opline->op2.opline_num - 1].result_type & EXT_TYPE_UNUSED) {
opline->result_type |= EXT_TYPE_UNUSED;
}
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
break;
case ZEND_FE_FETCH_R:
+1 -5
View File
@@ -397,7 +397,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define IS_TYPE_REFCOUNTED (1<<2)
#define IS_TYPE_COLLECTABLE (1<<3)
#define IS_TYPE_COPYABLE (1<<4)
#define IS_TYPE_SYMBOLTABLE (1<<5)
/* extended types */
#define IS_INTERNED_STRING_EX IS_STRING
@@ -474,9 +473,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define Z_IMMUTABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_IMMUTABLE) != 0)
#define Z_IMMUTABLE_P(zval_p) Z_IMMUTABLE(*(zval_p))
#define Z_SYMBOLTABLE(zval) ((Z_TYPE_FLAGS(zval) & IS_TYPE_SYMBOLTABLE) != 0)
#define Z_SYMBOLTABLE_P(zval_p) Z_SYMBOLTABLE(*(zval_p))
/* the following Z_OPT_* macros make better code when Z_TYPE_INFO accessed before */
#define Z_OPT_TYPE(zval) (Z_TYPE_INFO(zval) & Z_TYPE_MASK)
#define Z_OPT_TYPE_P(zval_p) Z_OPT_TYPE(*(zval_p))
@@ -813,7 +809,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z))
static zend_always_inline uint32_t zval_refcount_p(zval* pz) {
ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz) || Z_SYMBOLTABLE_P(pz));
ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz));
return GC_REFCOUNT(Z_COUNTED_P(pz));
}
+157 -148
View File
@@ -685,7 +685,7 @@ ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
ZVAL_FALSE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_TRUE(EX_VAR(opline->result.var));
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -699,7 +699,7 @@ ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, binary_op_type binary_op)
ZEND_VM_HELPER(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, binary_op_type binary_op)
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data1;
@@ -764,7 +764,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, binary_op_type binary_op)
ZEND_VM_HELPER(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, binary_op_type binary_op)
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data1;
@@ -835,7 +835,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMPVAR|
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_op_type binary_op)
ZEND_VM_HELPER(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_op_type binary_op)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -872,247 +872,247 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|CV, CONST|TMPVAR|CV, binary_
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(23, ZEND_ASSIGN_ADD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, add_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, add_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, add_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, add_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, add_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, add_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, add_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, add_function);
#endif
}
ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(24, ZEND_ASSIGN_SUB, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, sub_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, sub_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, sub_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, sub_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, sub_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, sub_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, sub_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, sub_function);
#endif
}
ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(25, ZEND_ASSIGN_MUL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mul_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, mul_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mul_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mul_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, mul_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, mul_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mul_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mul_function);
#endif
}
ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(26, ZEND_ASSIGN_DIV, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, div_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, div_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, div_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, div_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, div_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, div_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, div_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, div_function);
#endif
}
ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(27, ZEND_ASSIGN_MOD, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, mod_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, mod_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mod_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mod_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, mod_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, mod_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, mod_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, mod_function);
#endif
}
ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(28, ZEND_ASSIGN_SL, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_left_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, shift_left_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_left_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_left_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, shift_left_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, shift_left_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_left_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_left_function);
#endif
}
ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(29, ZEND_ASSIGN_SR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, shift_right_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, shift_right_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_right_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_right_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, shift_right_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, shift_right_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, shift_right_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, shift_right_function);
#endif
}
ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(30, ZEND_ASSIGN_CONCAT, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, concat_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, concat_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, concat_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, concat_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, concat_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, concat_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, concat_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, concat_function);
#endif
}
ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(31, ZEND_ASSIGN_BW_OR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_or_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_or_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, bitwise_or_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, bitwise_or_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_or_function);
#endif
}
ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(32, ZEND_ASSIGN_BW_AND, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_and_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_and_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, bitwise_and_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, bitwise_and_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_and_function);
#endif
}
ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(33, ZEND_ASSIGN_BW_XOR, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, bitwise_xor_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, bitwise_xor_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, bitwise_xor_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, bitwise_xor_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, bitwise_xor_function);
#endif
}
ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, DIM_OBJ)
ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|UNUSED|NEXT|CV, DIM_OBJ)
{
#if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
USE_OPLINE
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
if (EXPECTED(opline->extended_value == 0)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op, pow_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_helper, binary_op, pow_function);
}
# endif
if (EXPECTED(opline->extended_value == ZEND_ASSIGN_DIM)) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, pow_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, pow_function);
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, pow_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_obj_helper, binary_op, pow_function);
}
#else
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_dim_helper, binary_op, pow_function);
ZEND_VM_DISPATCH_TO_HELPER(zend_binary_assign_op_dim_helper, binary_op, pow_function);
#endif
}
ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc)
ZEND_VM_HELPER(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -1183,17 +1183,17 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, inc, 1);
ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_property_helper, inc, 1);
}
ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_pre_incdec_property_helper, inc, 0);
ZEND_VM_DISPATCH_TO_HELPER(zend_pre_incdec_property_helper, inc, 0);
}
ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc)
ZEND_VM_HELPER(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, int inc)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -1260,14 +1260,14 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, inc, 1);
ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_property_helper, inc, 1);
}
ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_post_incdec_property_helper, inc, 0);
ZEND_VM_DISPATCH_TO_HELPER(zend_post_incdec_property_helper, inc, 0);
}
ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
@@ -1470,7 +1470,7 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
{
USE_OPLINE
zend_free_op free_op1;
@@ -1566,41 +1566,41 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int ty
ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R);
}
ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W);
}
ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_RW);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_RW);
}
ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ARG_NUM)
{
USE_OPLINE
if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_W);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W);
} else {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_R);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R);
}
}
ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
}
ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_IS);
}
ZEND_VM_HELPER_EX(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, int type)
ZEND_VM_HELPER(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|VAR, int type)
{
USE_OPLINE
zend_free_op free_op1;
@@ -1652,6 +1652,10 @@ ZEND_VM_HELPER_EX(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (OP1_TYPE != IS_CONST) {
zend_string_release(name);
}
FREE_OP1();
HANDLE_EXCEPTION();
}
} else {
@@ -1672,6 +1676,9 @@ ZEND_VM_HELPER_EX(zend_fetch_static_prop_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if (OP1_TYPE != IS_CONST) {
zend_string_release(name);
}
FREE_OP1();
HANDLE_EXCEPTION();
}
@@ -1698,40 +1705,40 @@ ZEND_VM_C_LABEL(fetch_static_prop_return):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_R);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R);
}
ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_W);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W);
}
ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_RW);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_RW);
}
ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, NUM)
{
USE_OPLINE
if (zend_is_by_ref_func_arg_fetch(opline, EX(call))) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_W);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W);
} else {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_R);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R);
}
}
ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_UNSET);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_UNSET);
}
ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
{
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_static_prop_helper, type, BP_VAR_IS);
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_IS);
}
ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
@@ -1748,7 +1755,7 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|CV)
ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -1770,7 +1777,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|CV)
ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -1806,7 +1813,7 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|CV)
ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, NUM)
{
USE_OPLINE
zval *container;
@@ -1871,7 +1878,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1;
@@ -1944,7 +1951,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_no_object):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -1975,7 +1982,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -2005,7 +2012,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1;
@@ -2078,7 +2085,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM)
{
USE_OPLINE
zval *container;
@@ -2120,7 +2127,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPV
}
}
ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -2195,7 +2202,7 @@ ZEND_VM_C_LABEL(try_fetch_list):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -2225,7 +2232,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|CV)
ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
{
USE_OPLINE
zend_free_op free_op1;
@@ -2359,7 +2366,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -2461,7 +2468,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
if (UNEXPECTED(EG(exception) != NULL)) {
const zend_op *old_opline = EX(opline);
zend_throw_exception_internal(NULL);
if (RETURN_VALUE_USED(old_opline)) {
if (old_opline->opcode != ZEND_HANDLE_EXCEPTION && RETURN_VALUE_USED(old_opline)) {
zval_ptr_dtor(EX_VAR(old_opline->result.var));
}
HANDLE_EXCEPTION_LEAVE();
@@ -2967,7 +2974,7 @@ ZEND_VM_C_LABEL(try_class_name):
}
}
ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV, NUM)
ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM)
{
USE_OPLINE
zval *function_name;
@@ -3088,7 +3095,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CONST|VAR, CONST|TMPVAR|UNUSED|CV, NUM)
ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMPVAR|UNUSED|CONSTRUCTOR|CV, NUM)
{
USE_OPLINE
zval *function_name;
@@ -3117,6 +3124,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CONST|VAR, CONST|TMPVA
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
FREE_UNFETCHED_OP2();
HANDLE_EXCEPTION();
}
} else {
@@ -4064,7 +4072,7 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
}
ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC)
{
USE_OPLINE
zval *retval_ptr;
@@ -4348,7 +4356,7 @@ ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, NUM)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, NUM)
ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR, NUM, SEND)
{
USE_OPLINE
zend_free_op free_op1;
@@ -4897,7 +4905,7 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
ZVAL_TRUE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -4977,7 +4985,7 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CONST|VAR, JMP_ADDR, NUM)
ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, JMP_ADDR, NUM)
{
USE_OPLINE
zval object_zval;
@@ -5035,7 +5043,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CONST|VAR, JMP_ADDR, NUM)
}
}
ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY)
ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
{
USE_OPLINE
zend_free_op free_op1;
@@ -5074,19 +5082,15 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY)
} while (0);
ce = Z_OBJCE_P(obj);
clone = ce ? ce->clone : NULL;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
clone = ce->clone;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
if (UNEXPECTED(clone_call == NULL)) {
if (ce) {
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
} else {
zend_throw_error(NULL, "Trying to clone an uncloneable object");
}
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
FREE_OP1();
HANDLE_EXCEPTION();
}
if (ce && clone) {
if (clone) {
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
@@ -5106,12 +5110,11 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|CV, ANY)
}
}
if (EXPECTED(EG(exception) == NULL)) {
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
FREE_OP1();
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
@@ -5160,7 +5163,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST, CONST_FETCH)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED, CONST)
ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CONST)
{
zend_class_entry *ce;
zend_class_constant *c;
@@ -5242,7 +5245,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED, CONST)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|CV, NUM)
ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, REF)
{
USE_OPLINE
zend_free_op free_op1;
@@ -5341,7 +5344,7 @@ ZEND_VM_C_LABEL(num_index):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|CV, ARRAY_INIT)
ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|UNUSED|NEXT|CV, ARRAY_INIT|REF)
{
zval *array;
uint32_t size;
@@ -5603,7 +5606,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
{
USE_OPLINE
zval tmp, *varname;
@@ -5658,7 +5661,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
{
USE_OPLINE
zval tmp, *varname;
@@ -5698,6 +5701,10 @@ ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
FREE_OP1();
HANDLE_EXCEPTION();
}
} else {
@@ -5712,7 +5719,7 @@ ZEND_VM_HANDLER(179, ZEND_UNSET_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -5811,7 +5818,7 @@ ZEND_VM_C_LABEL(num_index_dim):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -6552,7 +6559,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|
}
}
ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CONST|VAR, ISSET)
ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, ISSET)
{
USE_OPLINE
zval *value;
@@ -6591,6 +6598,10 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, CONST|TMPVAR|CV, UNUSED|CON
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
FREE_OP1();
HANDLE_EXCEPTION();
}
} else {
@@ -6632,7 +6643,7 @@ ZEND_VM_C_LABEL(is_static_prop_return):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV, ISSET)
ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -6769,7 +6780,7 @@ ZEND_VM_C_LABEL(isset_dim_obj_exit):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV, ISSET)
ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -7133,7 +7144,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CONST|VAR)
ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
{
USE_OPLINE
zend_free_op free_op1;
@@ -7162,6 +7173,7 @@ ZEND_VM_C_LABEL(try_instanceof):
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
FREE_OP1();
HANDLE_EXCEPTION();
}
} else {
@@ -7452,7 +7464,7 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSED)
ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSED, SRC)
{
USE_OPLINE
@@ -7908,7 +7920,7 @@ ZEND_VM_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|VAR|CV, ANY, TYPE)
if (OP1_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
result = 1;
}
@@ -7941,7 +7953,6 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY)
result = 1;
} else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op1), 0)) == NULL) {
result = 0;
ZVAL_FALSE(EX_VAR(opline->result.var));
} else {
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), c);
result = 1;
@@ -7957,10 +7968,8 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, JMP_ADDR)
if (EG(assertions) <= 0) {
zend_op *target = OP_JMP_ADDR(opline, opline->op2);
zend_op *result = target - 1;
SKIP_EXT_OPLINE(result);
if (RETURN_VALUE_USED(result)) {
ZVAL_TRUE(EX_VAR(result->result.var));
if (RETURN_VALUE_USED(opline)) {
ZVAL_TRUE(EX_VAR(opline->result.var));
}
ZEND_VM_JMP(target);
} else {
+195 -68
View File
@@ -501,7 +501,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
if (UNEXPECTED(EG(exception) != NULL)) {
const zend_op *old_opline = EX(opline);
zend_throw_exception_internal(NULL);
if (RETURN_VALUE_USED(old_opline)) {
if (old_opline->opcode != ZEND_HANDLE_EXCEPTION && RETURN_VALUE_USED(old_opline)) {
zval_ptr_dtor(EX_VAR(old_opline->result.var));
}
HANDLE_EXCEPTION_LEAVE();
@@ -1675,10 +1675,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND
if (EG(assertions) <= 0) {
zend_op *target = OP_JMP_ADDR(opline, opline->op2);
zend_op *result = target - 1;
SKIP_EXT_OPLINE(result);
if (RETURN_VALUE_USED(result)) {
ZVAL_TRUE(EX_VAR(result->result.var));
if (RETURN_VALUE_USED(opline)) {
ZVAL_TRUE(EX_VAR(opline->result.var));
}
ZEND_VM_JMP(target);
} else {
@@ -2843,7 +2841,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CONST_HANDLER(ZE
ZVAL_FALSE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_TRUE(EX_VAR(opline->result.var));
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -3330,7 +3328,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_O
ZVAL_TRUE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -3441,19 +3439,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_
} while (0);
ce = Z_OBJCE_P(obj);
clone = ce ? ce->clone : NULL;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
clone = ce->clone;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
if (UNEXPECTED(clone_call == NULL)) {
if (ce) {
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
} else {
zend_throw_error(NULL, "Trying to clone an uncloneable object");
}
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
HANDLE_EXCEPTION();
}
if (ce && clone) {
if (clone) {
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
@@ -3473,11 +3467,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_
}
}
if (EXPECTED(EG(exception) == NULL)) {
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -4259,7 +4251,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CONST_HANDLER(
if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
result = 1;
}
@@ -4292,7 +4284,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEN
result = 1;
} else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op1), 0)) == NULL) {
result = 0;
ZVAL_FALSE(EX_VAR(opline->result.var));
} else {
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), c);
result = 1;
@@ -4991,6 +4982,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CONST != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
} else {
@@ -5011,6 +5006,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if (IS_CONST != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
@@ -5586,6 +5584,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -6073,6 +6072,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_C
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -6126,6 +6129,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -6791,6 +6798,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CONST != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
} else {
@@ -6811,6 +6822,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if (IS_CONST != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
@@ -6911,6 +6925,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_V
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -6964,6 +6982,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -7327,6 +7349,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CONST != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
} else {
@@ -7347,6 +7373,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if (IS_CONST != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
@@ -7478,6 +7507,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -7869,6 +7899,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CONST_U
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -7979,6 +8013,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -9290,6 +9328,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -11104,6 +11143,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
HANDLE_EXCEPTION();
}
} else {
@@ -12488,7 +12528,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZE
if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
result = 1;
}
@@ -16301,7 +16341,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_VAR_HANDLER(ZE
if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
result = 1;
}
@@ -17435,6 +17475,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -19044,6 +19085,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -20669,6 +20711,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -22245,6 +22288,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
HANDLE_EXCEPTION();
}
} else {
@@ -22726,19 +22770,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND
} while (0);
ce = Z_OBJCE_P(obj);
clone = ce ? ce->clone : NULL;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
clone = ce->clone;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
if (UNEXPECTED(clone_call == NULL)) {
if (ce) {
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
} else {
zend_throw_error(NULL, "Trying to clone an uncloneable object");
}
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
HANDLE_EXCEPTION();
}
if (ce && clone) {
if (clone) {
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
@@ -22758,11 +22798,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND
}
}
if (EXPECTED(EG(exception) == NULL)) {
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -23817,6 +23855,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -25171,6 +25210,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -26529,6 +26569,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -28162,6 +28203,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
ce = zend_fetch_class(NULL, opline->op1.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
HANDLE_EXCEPTION();
}
} else {
@@ -28654,7 +28696,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_
ZVAL_FALSE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_TRUE(EX_VAR(opline->result.var));
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -29434,7 +29476,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCO
ZVAL_TRUE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -29487,19 +29529,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
} while (0);
ce = Z_OBJCE_P(obj);
clone = ce ? ce->clone : NULL;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
clone = ce->clone;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
if (UNEXPECTED(clone_call == NULL)) {
if (ce) {
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
} else {
zend_throw_error(NULL, "Trying to clone an uncloneable object");
}
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
HANDLE_EXCEPTION();
}
if (ce && clone) {
if (clone) {
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
@@ -29519,11 +29557,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
}
}
if (EXPECTED(EG(exception) == NULL)) {
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -30305,7 +30341,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEN
if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(value) == IS_OBJECT)) {
zend_class_entry *ce = Z_OBJCE_P(value);
if (UNEXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
if (EXPECTED(ZSTR_LEN(ce->name) != sizeof("__PHP_Incomplete_Class") - 1) ||
EXPECTED(memcmp(ZSTR_VAL(ce->name), "__PHP_Incomplete_Class", sizeof("__PHP_Incomplete_Class") - 1) != 0)) {
result = 1;
}
@@ -31584,6 +31620,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CV != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
} else {
@@ -31604,6 +31644,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if (IS_CV != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
@@ -32709,6 +32752,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_CONS
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -32903,6 +32950,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -33155,6 +33206,7 @@ try_instanceof:
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -33701,6 +33753,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CV != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
} else {
@@ -33721,6 +33777,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if (IS_CV != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
@@ -33908,6 +33967,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_VAR_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -33961,6 +34024,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -34030,6 +34097,7 @@ try_instanceof:
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -34684,6 +34752,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CV != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
} else {
@@ -34704,6 +34776,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if (IS_CV != IS_CONST) {
zend_string_release(name);
}
HANDLE_EXCEPTION();
}
@@ -35236,6 +35311,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_CV_UNUS
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -35346,6 +35425,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
HANDLE_EXCEPTION();
}
} else {
@@ -35415,6 +35498,7 @@ try_instanceof:
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
HANDLE_EXCEPTION();
}
} else {
@@ -40723,7 +40807,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(Z
ZVAL_FALSE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_TRUE(EX_VAR(opline->result.var));
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -40990,7 +41074,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_
ZVAL_TRUE(EX_VAR(opline->result.var));
} else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
ZVAL_FALSE(EX_VAR(opline->result.var));
if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
SAVE_OPLINE();
GET_OP1_UNDEF_CV(val, BP_VAR_R);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -41043,19 +41127,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND
} while (0);
ce = Z_OBJCE_P(obj);
clone = ce ? ce->clone : NULL;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
clone = ce->clone;
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
if (UNEXPECTED(clone_call == NULL)) {
if (ce) {
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
} else {
zend_throw_error(NULL, "Trying to clone an uncloneable object");
}
zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name));
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
if (ce && clone) {
if (clone) {
if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
@@ -41075,12 +41155,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND
}
}
if (EXPECTED(EG(exception) == NULL)) {
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(!RETURN_VALUE_USED(opline)) || UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj));
if (UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var)));
}
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
@@ -41939,6 +42018,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zend_string_release(name);
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -41959,6 +42042,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zend_string_release(name);
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -42458,6 +42544,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -42511,6 +42601,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -42764,6 +42858,7 @@ try_instanceof:
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -42837,6 +42932,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zend_string_release(name);
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -42857,6 +42956,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zend_string_release(name);
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -42959,6 +43061,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -43012,6 +43118,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -43082,6 +43192,7 @@ try_instanceof:
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -43285,6 +43396,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zend_string_release(name);
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -43305,6 +43420,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_
}
retval = zend_std_get_static_property(ce, name, 0);
if (UNEXPECTED(EG(exception))) {
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
zend_string_release(name);
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
@@ -43462,6 +43580,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP_SPEC_TMPVAR_
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -43573,6 +43695,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
zend_string_release(Z_STR(tmp));
}
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
@@ -43643,6 +43769,7 @@ try_instanceof:
ce = zend_fetch_class(NULL, opline->op2.num);
if (UNEXPECTED(ce == NULL)) {
ZEND_ASSERT(EG(exception));
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
} else {
+114 -67
View File
@@ -58,32 +58,47 @@ $vm_op_flags = array(
"ZEND_VM_OP1_SPEC" => 1<<0,
"ZEND_VM_OP1_CONST" => 1<<1,
"ZEND_VM_OP1_TMPVAR" => 1<<2,
"ZEND_VM_OP1_NUM" => 1<<3,
"ZEND_VM_OP1_JMP_ADDR" => 1<<4,
"ZEND_VM_OP1_TRY_CATCH" => 1<<5,
"ZEND_VM_OP1_LIVE_RANGE" => 1<<6,
"ZEND_VM_OP1_MASK" => 0xf0,
"ZEND_VM_OP1_NUM" => 0x10,
"ZEND_VM_OP1_JMP_ADDR" => 0x20,
"ZEND_VM_OP1_TRY_CATCH" => 0x30,
"ZEND_VM_OP1_LIVE_RANGE" => 0x40,
"ZEND_VM_OP1_THIS" => 0x50,
"ZEND_VM_OP1_NEXT" => 0x60,
"ZEND_VM_OP1_CLASS_FETCH" => 0x70,
"ZEND_VM_OP1_CONSTRUCTOR" => 0x80,
"ZEND_VM_OP2_SPEC" => 1<<8,
"ZEND_VM_OP2_CONST" => 1<<9,
"ZEND_VM_OP2_TMPVAR" => 1<<10,
"ZEND_VM_OP2_NUM" => 1<<11,
"ZEND_VM_OP2_JMP_ADDR" => 1<<12,
"ZEND_VM_OP2_TRY_CATCH" => 1<<13,
"ZEND_VM_OP2_LIVE_RANGE" => 1<<14,
"ZEND_VM_OP2_MASK" => 0xf000,
"ZEND_VM_OP2_NUM" => 0x1000,
"ZEND_VM_OP2_JMP_ADDR" => 0x2000,
"ZEND_VM_OP2_TRY_CATCH" => 0x3000,
"ZEND_VM_OP2_LIVE_RANGE" => 0x4000,
"ZEND_VM_OP2_THIS" => 0x5000,
"ZEND_VM_OP2_NEXT" => 0x6000,
"ZEND_VM_OP2_CLASS_FETCH" => 0x7000,
"ZEND_VM_OP2_CONSTRUCTOR" => 0x8000,
"ZEND_VM_EXT_NUM" => 1<<16,
"ZEND_VM_EXT_VAR" => 1<<17,
"ZEND_VM_EXT_JMP_ADDR" => 1<<18,
"ZEND_VM_EXT_DIM_OBJ" => 1<<19,
"ZEND_VM_EXT_CLASS_FETCH" => 1<<20,
"ZEND_VM_EXT_CONST_FETCH" => 1<<21,
"ZEND_VM_EXT_VAR_FETCH" => 1<<22,
"ZEND_VM_EXT_ARRAY_INIT" => 1<<23,
"ZEND_VM_EXT_TYPE" => 1<<24,
"ZEND_VM_EXT_EVAL" => 1<<25,
"ZEND_VM_EXT_FAST_CALL" => 1<<26,
"ZEND_VM_EXT_FAST_RET" => 1<<27,
"ZEND_VM_EXT_ISSET" => 1<<28,
"ZEND_VM_EXT_VAR_FETCH" => 1<<16,
"ZEND_VM_EXT_ISSET" => 1<<17,
"ZEND_VM_EXT_ARG_NUM" => 1<<18,
"ZEND_VM_EXT_ARRAY_INIT" => 1<<19,
"ZEND_VM_EXT_REF" => 1<<20,
"ZEND_VM_EXT_MASK" => 0xff000000,
"ZEND_VM_EXT_NUM" => 0x01000000,
"ZEND_VM_EXT_VAR" => 0x02000000,
"ZEND_VM_EXT_JMP_ADDR" => 0x03000000,
"ZEND_VM_EXT_DIM_OBJ" => 0x04000000,
"ZEND_VM_EXT_CLASS_FETCH" => 0x05000000,
"ZEND_VM_EXT_CONST_FETCH" => 0x06000000,
"ZEND_VM_EXT_TYPE" => 0x07000000,
"ZEND_VM_EXT_EVAL" => 0x08000000,
"ZEND_VM_EXT_FAST_CALL" => 0x09000000,
"ZEND_VM_EXT_FAST_RET" => 0x0a000000,
"ZEND_VM_EXT_SRC" => 0x0b000000,
"ZEND_VM_EXT_SEND" => 0x0c000000,
);
foreach ($vm_op_flags as $name => $val) {
@@ -102,6 +117,10 @@ $vm_op_decode = array(
"JMP_ADDR" => ZEND_VM_OP1_JMP_ADDR,
"TRY_CATCH" => ZEND_VM_OP1_TRY_CATCH,
"LIVE_RANGE" => ZEND_VM_OP1_LIVE_RANGE,
"THIS" => ZEND_VM_OP1_THIS,
"NEXT" => ZEND_VM_OP1_NEXT,
"CLASS_FETCH" => ZEND_VM_OP1_CLASS_FETCH,
"CONSTRUCTOR" => ZEND_VM_OP1_CONSTRUCTOR,
);
$vm_ext_decode = array(
@@ -118,6 +137,10 @@ $vm_ext_decode = array(
"FAST_CALL" => ZEND_VM_EXT_FAST_CALL,
"FAST_RET" => ZEND_VM_EXT_FAST_RET,
"ISSET" => ZEND_VM_EXT_ISSET,
"ARG_NUM" => ZEND_VM_EXT_ARG_NUM,
"REF" => ZEND_VM_EXT_REF,
"SRC" => ZEND_VM_EXT_SRC,
"SEND" => ZEND_VM_EXT_SEND,
);
$vm_kind_name = array(
@@ -527,6 +550,25 @@ function helper_name($name, $spec, $op1, $op2) {
return $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2];
}
function opcode_name($name, $spec, $op1, $op2) {
global $prefix, $opnames, $opcodes;
if (isset($opnames[$name])) {
$opcode = $opcodes[$opnames[$name]];
// If we haven't helper with specified spicialized operands then
// using unspecialized helper
if (!isset($opcode["op1"][$op1]) &&
isset($opcode["op1"]["ANY"])) {
$op1 = "ANY";
}
if (!isset($opcode["op2"][$op2]) &&
isset($opcode["op2"]["ANY"])) {
$op2 = "ANY";
}
}
return $name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2];
}
// Generates code for opcode handler or helper
function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
global $op1_type, $op2_type, $op1_get_zval_ptr, $op2_get_zval_ptr,
@@ -645,17 +687,20 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
array(
"/EXECUTE_DATA/m",
"/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
"/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m",
"/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*[A-Za-z_]*\s*,\s*(.*)\s*\);/m",
"/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
),
function($matches) use ($spec, $prefix, $op1, $op2) {
if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
return "execute_data";
} else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
return "ZEND_VM_TAIL_CALL(" . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
} else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) {
return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2) . "(" . $matches[2]. " ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));";
return "ZEND_VM_TAIL_CALL(" . opcode_name($matches[1], $spec, $op1, $op2) . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
} else {
// ZEND_VM_DISPATCH_TO_HELPER
if (isset($matches[2])) {
// extra args
$args = substr(preg_replace("/,\s*[A-Za-z_]*\s*,\s*([^,)\s]*)\s*/", ", $1", $matches[2]), 2);
return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2) . "(" . $args. " ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC))";
}
return "ZEND_VM_TAIL_CALL(" . helper_name($matches[1], $spec, $op1, $op2) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU))";
}
},
@@ -666,17 +711,20 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
array(
"/EXECUTE_DATA/m",
"/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
"/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m",
"/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m",
"/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
),
function($matches) use ($spec, $prefix, $op1, $op2) {
if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
return "execute_data";
} else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
return "goto " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_LABEL";
} else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) {
return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";";
return "goto " . opcode_name($matches[1], $spec, $op1, $op2) . "_LABEL";
} else {
// ZEND_VM_DISPATCH_TO_HELPER
if (isset($matches[2])) {
// extra args
$args = preg_replace("/,\s*([A-Za-z_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
return $args . "goto " . helper_name($matches[1], $spec, $op1, $op2);
}
return "goto " . helper_name($matches[1], $spec, $op1, $op2);
}
},
@@ -687,17 +735,20 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
array(
"/EXECUTE_DATA/m",
"/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
"/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m",
"/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m",
"/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*(,[^)]*)?\)/m",
),
function($matches) use ($spec, $prefix, $op1, $op2) {
if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
return "execute_data";
} else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
return "goto " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_HANDLER";
} else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) {
return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";";
return "goto " . opcode_name($matches[1], $spec, $op1, $op2) . "_HANDLER";
} else {
// ZEND_VM_DISPATCH_TO_HELPER
if (isset($matches[2])) {
// extra args
$args = preg_replace("/,\s*([A-Za-z_]*)\s*,\s*([^,)\s]*)\s*/", "$1 = $2; ", $matches[2]);
return $args . "goto " . helper_name($matches[1], $spec, $op1, $op2);
}
return "goto " . helper_name($matches[1], $spec, $op1, $op2);
}
},
@@ -782,7 +833,7 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno)
}
// Generates helper
function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno) {
function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline) {
global $definition_file, $prefix;
if (ZEND_VM_LINES) {
@@ -792,12 +843,19 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno)
// Generate helper's entry point according to selected threading model
switch($kind) {
case ZEND_VM_KIND_CALL:
if ($inline) {
$zend_always_inline = " zend_always_inline";
$zend_fastcall = "";
} else {
$zend_always_inline = "";
$zend_fastcall = " ZEND_FASTCALL";
}
if ($param == null) {
// Helper without parameters
out($f, "static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."(ZEND_OPCODE_HANDLER_ARGS)\n");
out($f, "static$zend_always_inline ZEND_OPCODE_HANDLER_RET$zend_fastcall ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."(ZEND_OPCODE_HANDLER_ARGS)\n");
} else {
// Helper with parameter
out($f, "static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."(".$param." ZEND_OPCODE_HANDLER_ARGS_DC)\n");
out($f, "static$zend_always_inline ZEND_OPCODE_HANDLER_RET$zend_fastcall ".$name.($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."(".$param." ZEND_OPCODE_HANDLER_ARGS_DC)\n");
}
break;
case ZEND_VM_KIND_SWITCH:
@@ -1023,7 +1081,7 @@ function gen_executor_code($f, $spec, $kind, $prolog) {
if (isset($helpers[$num]["op1"][$op1]) &&
isset($helpers[$num]["op2"][$op2])) {
// Generate helper code
gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno);
gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"]);
}
} else {
var_dump($dsc);
@@ -1044,7 +1102,7 @@ function gen_executor_code($f, $spec, $kind, $prolog) {
} else if (isset($dsc["helper"])) {
$num = $dsc["helper"];
// Generate helper code
gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno);
gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"]);
} else {
var_dump($dsc);
die("??? $kind:$num\n");
@@ -1477,43 +1535,32 @@ function gen_vm($def, $skel) {
$handler = $code;
$helper = null;
$list[$lineno] = array("handler"=>$handler);
} else if (strpos($line,"ZEND_VM_HELPER(") === 0) {
} else if (strpos($line,"ZEND_VM_HELPER(") === 0 || strpos($line,"ZEND_VM_INLINE_HELPER(") === 0) {
// Parsing helper's definition
if (preg_match(
"/^ZEND_VM_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*\)/",
"/^ZEND_VM(_INLINE)?_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(?:,\s*([^)]*))?\s*\)/",
$line,
$m) == 0) {
die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n");
}
$helper = $m[1];
$op1 = parse_operand_spec($def, $lineno, $m[2], $flags1);
$op2 = parse_operand_spec($def, $lineno, $m[3], $flags2);
if (isset($helpers[$helper])) {
die("ERROR ($def:$lineno): Helper with name '$helper' is already defined.\n");
}
$helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>null,"code"=>"");
$handler = null;
$list[$lineno] = array("helper"=>$helper);
} else if (strpos($line,"ZEND_VM_HELPER_EX(") === 0) {
// Parsing helper with parameter definition
if (preg_match(
"/^ZEND_VM_HELPER_EX\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*,\s*(.*)\s*\)/",
$line,
$m) == 0) {
die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n");
}
$helper = $m[1];
$op1 = parse_operand_spec($def, $lineno, $m[2], $flags1);
$op2 = parse_operand_spec($def, $lineno, $m[3], $flags2);
$param = $m[4];
$inline = !empty($m[1]);
$helper = $m[2];
$op1 = parse_operand_spec($def, $lineno, $m[3], $flags1);
$op2 = parse_operand_spec($def, $lineno, $m[4], $flags2);
$param = isset($m[5]) ? $m[5] : null;
if (isset($helpers[$helper])) {
die("ERROR ($def:$lineno): Helper with name '$helper' is already defined.\n");
}
// Store parameter
$params[$param] = 1;
// Store parameters
foreach (explode(",", $param) as $p) {
$p = trim($p);
if ($p !== "") {
$params[$p] = 1;
}
}
$helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"");
$helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"","inline"=>$inline);
$handler = null;
$list[$lineno] = array("helper"=>$helper);
} else if (strpos($line,"ZEND_VM_EXPORT_HANDLER(") === 0) {
+106 -106
View File
@@ -228,167 +228,167 @@ static uint32_t zend_vm_opcodes_flags[182] = {
0x00000707,
0x00000707,
0x00000707,
0x01000003,
0x07000003,
0x00000003,
0x00080701,
0x00080701,
0x00080701,
0x00080701,
0x00080701,
0x00080701,
0x00080701,
0x00080701,
0x00080701,
0x00080701,
0x00080701,
0x04006751,
0x04006751,
0x04006751,
0x04006751,
0x04006751,
0x04006751,
0x04006751,
0x04006751,
0x04006751,
0x04006751,
0x04006751,
0x00000001,
0x00000001,
0x00000001,
0x00000001,
0x00000301,
0x00000101,
0x0b000101,
0x00000007,
0x00000000,
0x00000010,
0x00001007,
0x00001007,
0x00041007,
0x00001007,
0x00001007,
0x00000020,
0x00002007,
0x00002007,
0x03002007,
0x00002007,
0x00002007,
0x00000707,
0x00000000,
0x00000000,
0x00000000,
0x00000007,
0x00000707,
0x00010701,
0x00010701,
0x00010701,
0x01000701,
0x01000701,
0x01000701,
0x00000000,
0x00000001,
0x00010300,
0x01000300,
0x00000000,
0x00010300,
0x01000300,
0x00000003,
0x00000008,
0x00000308,
0x00000803,
0x00000801,
0x00000801,
0x00011003,
0x00010300,
0x00004005,
0x00800703,
0x00010703,
0x02000007,
0x00400107,
0x00000701,
0x00000701,
0x00000010,
0x00000310,
0x00001003,
0x00040001,
0x00001001,
0x00001001,
0x01002073,
0x01000300,
0x00004005,
0x00186703,
0x00106703,
0x08000007,
0x00030107,
0x00000751,
0x00000751,
0x00002003,
0x03000001,
0x00000007,
0x00400107,
0x00010107,
0x00000707,
0x00000703,
0x00400107,
0x00000701,
0x00000701,
0x00400107,
0x00000701,
0x00000701,
0x00400107,
0x00000753,
0x00010107,
0x00006701,
0x00000751,
0x00010107,
0x00006701,
0x00000751,
0x00010107,
0x00000707,
0x00000707,
0x00400107,
0x00000703,
0x00000703,
0x00400107,
0x00000701,
0x00000757,
0x00050107,
0x01006703,
0x01000753,
0x00010107,
0x00000701,
0x00000751,
0x00000307,
0x00200301,
0x06000301,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00010000,
0x00000801,
0x00040103,
0x01000000,
0x0c001001,
0x03000103,
0x00000003,
0x00100700,
0x00000007,
0x00000003,
0x00010707,
0x00010703,
0x10400107,
0x10000707,
0x00000803,
0x00000801,
0x00010703,
0x00000000,
0x00000801,
0x00000007,
0x00000003,
0x01000003,
0x00000103,
0x05000700,
0x00000057,
0x0b000003,
0x01000757,
0x01008773,
0x00030107,
0x00020757,
0x00001003,
0x00040001,
0x00001001,
0x01000703,
0x00000000,
0x00001001,
0x00000007,
0x00000003,
0x07000003,
0x00000103,
0x00002003,
0x03000001,
0x00004005,
0x00010700,
0x01000700,
0x00000000,
0x00000000,
0x00000000,
0x00000701,
0x00000701,
0x00000701,
0x00000701,
0x00000701,
0x00000751,
0x00000751,
0x00000751,
0x00000751,
0x00000751,
0x00000000,
0x00000305,
0x00007305,
0x00000000,
0x00020000,
0x02000000,
0x00000000,
0x00000003,
0x00000303,
0x00000300,
0x00020000,
0x02000000,
0x00000000,
0x00000701,
0x10000707,
0x00006701,
0x00020757,
0x00000000,
0x00000000,
0x00001000,
0x00001003,
0x00002000,
0x00002003,
0x00000103,
0x00000000,
0x00000000,
0x00000101,
0x00100000,
0x05000000,
0x00000000,
0x00000000,
0x00000303,
0x0b000303,
0x00000003,
0x04002010,
0x08002000,
0x00000008,
0x09003020,
0x0a003000,
0x00000010,
0x00000000,
0x00000707,
0x00080701,
0x04006751,
0x00000301,
0x00001003,
0x00002003,
0x00000707,
0x00000010,
0x00020010,
0x00000307,
0x00000307,
0x00000307,
0x00000307,
0x00000307,
0x00000307,
0x00000307,
0x10000307,
0x00000303,
0x00000020,
0x02000020,
0x00007307,
0x00007307,
0x00007307,
0x00007307,
0x01007307,
0x00007307,
0x00007307,
0x00027307,
0x00000373,
};
ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {
+34 -19
View File
@@ -31,30 +31,45 @@
#define ZEND_VM_OP1_SPEC 0x00000001
#define ZEND_VM_OP1_CONST 0x00000002
#define ZEND_VM_OP1_TMPVAR 0x00000004
#define ZEND_VM_OP1_NUM 0x00000008
#define ZEND_VM_OP1_JMP_ADDR 0x00000010
#define ZEND_VM_OP1_TRY_CATCH 0x00000020
#define ZEND_VM_OP1_MASK 0x000000f0
#define ZEND_VM_OP1_NUM 0x00000010
#define ZEND_VM_OP1_JMP_ADDR 0x00000020
#define ZEND_VM_OP1_TRY_CATCH 0x00000030
#define ZEND_VM_OP1_LIVE_RANGE 0x00000040
#define ZEND_VM_OP1_THIS 0x00000050
#define ZEND_VM_OP1_NEXT 0x00000060
#define ZEND_VM_OP1_CLASS_FETCH 0x00000070
#define ZEND_VM_OP1_CONSTRUCTOR 0x00000080
#define ZEND_VM_OP2_SPEC 0x00000100
#define ZEND_VM_OP2_CONST 0x00000200
#define ZEND_VM_OP2_TMPVAR 0x00000400
#define ZEND_VM_OP2_NUM 0x00000800
#define ZEND_VM_OP2_JMP_ADDR 0x00001000
#define ZEND_VM_OP2_TRY_CATCH 0x00002000
#define ZEND_VM_OP2_MASK 0x0000f000
#define ZEND_VM_OP2_NUM 0x00001000
#define ZEND_VM_OP2_JMP_ADDR 0x00002000
#define ZEND_VM_OP2_TRY_CATCH 0x00003000
#define ZEND_VM_OP2_LIVE_RANGE 0x00004000
#define ZEND_VM_EXT_NUM 0x00010000
#define ZEND_VM_EXT_VAR 0x00020000
#define ZEND_VM_EXT_JMP_ADDR 0x00040000
#define ZEND_VM_EXT_DIM_OBJ 0x00080000
#define ZEND_VM_EXT_CLASS_FETCH 0x00100000
#define ZEND_VM_EXT_CONST_FETCH 0x00200000
#define ZEND_VM_EXT_VAR_FETCH 0x00400000
#define ZEND_VM_EXT_ARRAY_INIT 0x00800000
#define ZEND_VM_EXT_TYPE 0x01000000
#define ZEND_VM_EXT_EVAL 0x02000000
#define ZEND_VM_EXT_FAST_CALL 0x04000000
#define ZEND_VM_EXT_FAST_RET 0x08000000
#define ZEND_VM_EXT_ISSET 0x10000000
#define ZEND_VM_OP2_THIS 0x00005000
#define ZEND_VM_OP2_NEXT 0x00006000
#define ZEND_VM_OP2_CLASS_FETCH 0x00007000
#define ZEND_VM_OP2_CONSTRUCTOR 0x00008000
#define ZEND_VM_EXT_VAR_FETCH 0x00010000
#define ZEND_VM_EXT_ISSET 0x00020000
#define ZEND_VM_EXT_ARG_NUM 0x00040000
#define ZEND_VM_EXT_ARRAY_INIT 0x00080000
#define ZEND_VM_EXT_REF 0x00100000
#define ZEND_VM_EXT_MASK 0xff000000
#define ZEND_VM_EXT_NUM 0x01000000
#define ZEND_VM_EXT_VAR 0x02000000
#define ZEND_VM_EXT_JMP_ADDR 0x03000000
#define ZEND_VM_EXT_DIM_OBJ 0x04000000
#define ZEND_VM_EXT_CLASS_FETCH 0x05000000
#define ZEND_VM_EXT_CONST_FETCH 0x06000000
#define ZEND_VM_EXT_TYPE 0x07000000
#define ZEND_VM_EXT_EVAL 0x08000000
#define ZEND_VM_EXT_FAST_CALL 0x09000000
#define ZEND_VM_EXT_FAST_RET 0x0a000000
#define ZEND_VM_EXT_SRC 0x0b000000
#define ZEND_VM_EXT_SEND 0x0c000000
BEGIN_EXTERN_C()
+1 -1
View File
@@ -810,7 +810,7 @@ PHP_FUNCTION(com_message_pump)
}
/* }}} */
/* {{{ proto bool com_load_typelib(string typelib_name [, int case_insensitive])
/* {{{ proto bool com_load_typelib(string typelib_name [, bool case_insensitive])
Loads a Typelibrary and registers its constants */
PHP_FUNCTION(com_load_typelib)
{
+2 -2
View File
@@ -3579,9 +3579,9 @@ PHP_FUNCTION(date_diff)
zval *object1, *object2;
php_date_obj *dateobj1, *dateobj2;
php_interval_obj *interval;
zend_long absolute = 0;
zend_bool absolute = 0;
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "OO|l", &object1, date_ce_interface, &object2, date_ce_interface, &absolute) == FAILURE) {
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "OO|b", &object1, date_ce_interface, &object2, date_ce_interface, &absolute) == FAILURE) {
RETURN_FALSE;
}
dateobj1 = Z_PHPDATE_P(object1);
+5 -1
View File
@@ -320,6 +320,10 @@ if test "$PHP_DB4" != "no"; then
THIS_PREFIX=$i
THIS_INCLUDE=$i/db4/db.h
break
elif test -f "$i/include/db5.3/db.h"; then
THIS_PREFIX=$i
THIS_INCLUDE=$i/include/db5.3/db.h
break
elif test -f "$i/include/db5.1/db.h"; then
THIS_PREFIX=$i
THIS_INCLUDE=$i/include/db5.1/db.h
@@ -362,7 +366,7 @@ if test "$PHP_DB4" != "no"; then
break
fi
done
PHP_DBA_DB_CHECK(4, db-5.1 db-5.0 db-4.8 db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)])
PHP_DBA_DB_CHECK(4, db-5.3 db-5.1 db-5.0 db-4.8 db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)])
fi
PHP_DBA_STD_RESULT(db4,Berkeley DB4)
+13 -6
View File
@@ -209,7 +209,7 @@ static size_t php_dba_make_key(zval *key, char **key_str, char **key_free)
if (zend_hash_num_elements(Z_ARRVAL_P(key)) != 2) {
php_error_docref(NULL, E_RECOVERABLE_ERROR, "Key does not have exactly two elements: (key, name)");
return -1;
return 0;
}
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(key), &pos);
group = zend_hash_get_current_data_ex(Z_ARRVAL_P(key), &pos);
@@ -232,9 +232,10 @@ static size_t php_dba_make_key(zval *key, char **key_str, char **key_free)
ZVAL_COPY(&tmp, key);
convert_to_string(&tmp);
*key_free = *key_str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp));
len = Z_STRLEN(tmp);
if (len) {
*key_free = *key_str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp));
}
zval_ptr_dtor(&tmp);
return len;
}
@@ -281,8 +282,14 @@ static size_t php_dba_make_key(zval *key, char **key_str, char **key_free)
RETURN_FALSE; \
}
#define DBA_ID_GET2 DBA_ID_PARS; DBA_GET2; DBA_FETCH_RESOURCE(info, id)
#define DBA_ID_GET2_3 DBA_ID_PARS; DBA_GET2_3; DBA_FETCH_RESOURCE(info, id)
#define DBA_FETCH_RESOURCE_WITH_ID(info, id) \
if ((info = (dba_info *)zend_fetch_resource2(Z_RES_P(id), "DBA identifier", le_db, le_pdb)) == NULL) { \
DBA_ID_DONE; \
RETURN_FALSE; \
}
#define DBA_ID_GET2 DBA_ID_PARS; DBA_GET2; DBA_FETCH_RESOURCE_WITH_ID(info, id)
#define DBA_ID_GET2_3 DBA_ID_PARS; DBA_GET2_3; DBA_FETCH_RESOURCE_WITH_ID(info, id)
#define DBA_ID_DONE \
if (key_free) efree(key_free)
@@ -578,7 +585,7 @@ static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode)
RETURN_FALSE;
}
DBA_FETCH_RESOURCE(info, id);
DBA_FETCH_RESOURCE_WITH_ID(info, id);
DBA_WRITE_CHECK_WITH_ID;
+2 -2
View File
@@ -1348,9 +1348,9 @@ PHP_FUNCTION(dom_node_clone_node)
xmlNode *n, *node;
int ret;
dom_object *intern;
zend_long recursive = 0;
zend_bool recursive = 0;
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &id, dom_node_class_entry, &recursive) == FAILURE) {
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|b", &id, dom_node_class_entry, &recursive) == FAILURE) {
return;
}
+2 -2
View File
@@ -299,12 +299,12 @@ if test -n "$proto"; then
warning="
NOTE! Because some arguments to functions were resources, the code generated
cannot yet be compiled without editing. Please consider this to be step 4.5
in the instructions above.
in the instructions above.
"
fi
fi
find . -type f | xargs chmod 644
find . -type f | xargs chmod 644
find . -type d | xargs chmod 755
fi
+2
View File
@@ -4,6 +4,8 @@ Bug #71063 (filter_input(INPUT_ENV, ..) does not work)
<?php if (!extension_loaded("filter")) die("skip"); ?>
--ENV--
PATH=/
--INI--
variables_order=E
--FILE--
<?php
var_dump(count($_ENV['PATH']) > 0);
+5 -3
View File
@@ -754,10 +754,11 @@ ftp_pasv(ftpbuf_t *ftp, int pasv)
memset(&ftp->pasvaddr, 0, n);
sa = (struct sockaddr *) &ftp->pasvaddr;
#if HAVE_IPV6
if (getpeername(ftp->fd, sa, &n) < 0) {
return 0;
}
#if HAVE_IPV6
if (sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
char *endptr, delimiter;
@@ -810,8 +811,9 @@ ftp_pasv(ftpbuf_t *ftp, int pasv)
ipbox.c[n] = (unsigned char) b[n];
}
sin = (struct sockaddr_in *) sa;
sin->sin_family = AF_INET;
sin->sin_addr = ipbox.ia[0];
if (ftp->usepasvaddress) {
sin->sin_addr = ipbox.ia[0];
}
sin->sin_port = ipbox.s[2];
ftp->pasv = 2;
+2
View File
@@ -31,6 +31,7 @@
#define FTP_DEFAULT_TIMEOUT 90
#define FTP_DEFAULT_AUTOSEEK 1
#define FTP_DEFAULT_USEPASVADDRESS 1
#define PHP_FTP_FAILED 0
#define PHP_FTP_FINISHED 1
#define PHP_FTP_MOREDATA 2
@@ -71,6 +72,7 @@ typedef struct ftpbuf
php_sockaddr_storage pasvaddr; /* passive mode address */
zend_long timeout_sec; /* User configurable timeout (seconds) */
int autoseek; /* User configurable autoseek flag */
int usepasvaddress; /* Use the address returned by the pasv command */
int nb; /* "nonblocking" transfer in progress */
databuf_t *data; /* Data connection for "nonblocking" transfers */
+15
View File
@@ -326,6 +326,7 @@ PHP_MINIT_FUNCTION(ftp)
REGISTER_LONG_CONSTANT("FTP_AUTORESUME", PHP_FTP_AUTORESUME, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("FTP_TIMEOUT_SEC", PHP_FTP_OPT_TIMEOUT_SEC, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("FTP_AUTOSEEK", PHP_FTP_OPT_AUTOSEEK, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("FTP_USEPASVADDRESS", PHP_FTP_OPT_USEPASVADDRESS, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("FTP_FAILED", PHP_FTP_FAILED, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("FTP_FINISHED", PHP_FTP_FINISHED, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("FTP_MOREDATA", PHP_FTP_MOREDATA, CONST_PERSISTENT | CONST_CS);
@@ -379,6 +380,7 @@ PHP_FUNCTION(ftp_connect)
/* autoseek for resuming */
ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
#ifdef HAVE_FTP_SSL
/* disable ssl */
ftp->use_ssl = 0;
@@ -415,6 +417,7 @@ PHP_FUNCTION(ftp_ssl_connect)
/* autoseek for resuming */
ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
/* enable ssl */
ftp->use_ssl = 1;
@@ -1478,6 +1481,15 @@ PHP_FUNCTION(ftp_set_option)
ftp->autoseek = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0;
RETURN_TRUE;
break;
case PHP_FTP_OPT_USEPASVADDRESS:
if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) {
php_error_docref(NULL, E_WARNING, "Option USEPASVADDRESS expects value of type boolean, %s given",
zend_zval_type_name(z_value));
RETURN_FALSE;
}
ftp->usepasvaddress = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0;
RETURN_TRUE;
break;
default:
php_error_docref(NULL, E_WARNING, "Unknown option '%pd'", option);
RETURN_FALSE;
@@ -1509,6 +1521,9 @@ PHP_FUNCTION(ftp_get_option)
case PHP_FTP_OPT_AUTOSEEK:
RETURN_BOOL(ftp->autoseek);
break;
case PHP_FTP_OPT_USEPASVADDRESS:
RETURN_BOOL(ftp->usepasvaddress);
break;
default:
php_error_docref(NULL, E_WARNING, "Unknown option '%pd'", option);
RETURN_FALSE;
+1
View File
@@ -32,6 +32,7 @@ extern zend_module_entry php_ftp_module_entry;
#define PHP_FTP_OPT_TIMEOUT_SEC 0
#define PHP_FTP_OPT_AUTOSEEK 1
#define PHP_FTP_OPT_USEPASVADDRESS 2
#define PHP_FTP_AUTORESUME -1
PHP_MINIT_FUNCTION(ftp);
+10 -5
View File
@@ -20,9 +20,9 @@ AC_DEFUN([IMAP_LIB_CHK],[
done
])
dnl PHP_IMAP_TEST_BUILD(function, action-if-ok, action-if-not-ok, extra-libs)
dnl PHP_IMAP_TEST_BUILD(function, action-if-ok, action-if-not-ok, extra-libs, extra-source)
AC_DEFUN([PHP_IMAP_TEST_BUILD], [
PHP_TEST_BUILD([$1], [$2], [$3], [$4],
PHP_TEST_BUILD([$1], [$2], [$3], [$4], [$5]
[
#if defined(__GNUC__) && __GNUC__ >= 4
# define PHP_IMAP_EXPORT __attribute__ ((visibility("default")))
@@ -228,10 +228,15 @@ if test "$PHP_IMAP" != "no"; then
AC_DEFINE(HAVE_IMAP_AUTH_GSS, 1, [ ])
], [], $TST_LIBS)
dnl Check if utf8_to_mutf7 exists
PHP_IMAP_TEST_BUILD(utf8_to_mutf7, [
dnl Check if utf8_to_mutf7 exists. We need to do some gymnastics because
dnl utf8_to_mutf7 takes an argument and will segfault without it. We
dnl therefore test another function utf8_to_mutf7_php() which calls
dnl the utf8_to_mutf7() function with the empty string as an argument.
PHP_IMAP_TEST_BUILD(utf8_to_mutf7_php, [
AC_DEFINE(HAVE_IMAP_MUTF7, 1, [ ])
], [], $TST_LIBS)
], [], $TST_LIBS, [
char utf8_to_mutf7_php(){ return utf8_to_mutf7(""); }
])
AC_MSG_CHECKING(whether rfc822_output_address_list function present)
PHP_TEST_BUILD(foobar, [
-6
View File
@@ -143,17 +143,14 @@ PHP_FUNCTION(ibase_wait_event)
if (Z_TYPE(args[0]) == IS_RESOURCE) {
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(&args[0], "InterBase link", le_link, le_plink)) == NULL) {
efree(args);
RETURN_FALSE;
}
i = 1;
} else {
if (ZEND_NUM_ARGS() > 15) {
efree(args);
WRONG_PARAM_COUNT;
}
if ((ib_link = (ibase_db_link *)zend_fetch_resource2_ex(IBG(default_link), "InterBase link", le_link, le_plink)) == NULL) {
efree(args);
RETURN_FALSE;
}
}
@@ -170,7 +167,6 @@ PHP_FUNCTION(ibase_wait_event)
if (isc_wait_for_event(IB_STATUS, &ib_link->handle, buffer_size, event_buffer, result_buffer)) {
_php_ibase_error();
_php_ibase_event_free(event_buffer,result_buffer);
efree(args);
RETURN_FALSE;
}
@@ -180,7 +176,6 @@ PHP_FUNCTION(ibase_wait_event)
if (occurred_event[i]) {
zend_string *result = zend_string_init(events[i], strlen(events[i]), 0);
_php_ibase_event_free(event_buffer,result_buffer);
efree(args);
RETURN_STR(result);
}
}
@@ -188,7 +183,6 @@ PHP_FUNCTION(ibase_wait_event)
/* If we reach this line, isc_wait_for_event() did return, but we don't know
which event fired. */
_php_ibase_event_free(event_buffer,result_buffer);
efree(args);
RETURN_FALSE;
}
/* }}} */
-2
View File
@@ -505,8 +505,6 @@ void calendar_register_IntlCalendar_class(void)
CALENDAR_DECL_LONG_CONST("FIELD_AM_PM", UCAL_AM_PM);
CALENDAR_DECL_LONG_CONST("FIELD_HOUR", UCAL_HOUR);
CALENDAR_DECL_LONG_CONST("FIELD_HOUR_OF_DAY", UCAL_HOUR_OF_DAY);
CALENDAR_DECL_LONG_CONST("FIELD_HOUR", UCAL_HOUR);
CALENDAR_DECL_LONG_CONST("FIELD_HOUR_OF_DAY", UCAL_HOUR_OF_DAY);
CALENDAR_DECL_LONG_CONST("FIELD_MINUTE", UCAL_MINUTE);
CALENDAR_DECL_LONG_CONST("FIELD_SECOND", UCAL_SECOND);
CALENDAR_DECL_LONG_CONST("FIELD_MILLISECOND", UCAL_MILLISECOND);
+14 -8
View File
@@ -5,16 +5,22 @@ Use the OCI8 extension to access Oracle Database.
Documentation is at http://php.net/oci8
The extension can be linked with Oracle client libraries from Oracle
Database 10.2, 11, or 12.1. These libraries are found in the database
installation, or in the free Oracle Instant Client available from
Oracle.
PHP OCI8 2.1 builds with PHP 7.
Use 'pecl install oci8' to install OCI8 for PHP 7.
Use 'pecl install oci8-2.0.10' to install OCI8 for PHP 5.2 - PHP 5.6.
Use 'pecl install oci8-1.4.10' to install OCI8 for PHP 4.3.9 - PHP 5.1.
The OCI8 extension needs to be linked with Oracle 12.1, 11, or 10.2
client libraries. These libraries are found in your database
installation, or in the free Oracle Instant Client from
http://www.oracle.com/technetwork/database/features/instant-client/
Install the 'Basic' or 'Basic Lite' Instant Client package. If
building from source, then also install the SDK package.
Oracle's standard cross-version connectivity applies. For example,
PHP OCI8 linked with Instant Client 11.2 can connect to Oracle
Database 9.2 onward. See Oracle's note "Oracle Client / Server
Interoperability Support" (ID 207303.1) for details.
PHP OCI8 2.0 can be built with PHP 5.2 onward. Use the older PHP OCI8
1.4.10 when using PHP 4.3.9 through to PHP 5.1.x, or when only Oracle
Database 9.2 client libraries are available.
+1 -3
View File
@@ -40,10 +40,8 @@
/* PHP 5.2 is the minimum supported version for OCI8 2.0 */
#if PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION <= 1)
#error Use PHP OCI8 1.4 for your version of PHP
#endif
#elif PHP_MAJOR_VERSION < 7
/* PHP 7 is the minimum supported version for OCI8 2.1 */
#if PHP_MAJOR_VERSION < 7
#error Use PHP OCI8 2.0 for your version of PHP
#endif
+71 -67
View File
@@ -8,17 +8,18 @@ http://pear.php.net/dtd/package-2.0.xsd">
<summary>Extension for Oracle Database</summary>
<description>
Use the OCI8 extension to access Oracle Database. The extension can
be linked with Oracle client libraries from Oracle Database 10.2, 11,
or 12.1. These libraries are found in the database installation, or
in the free Oracle Instant Client available from Oracle. Oracle's
standard cross-version connectivity applies. For example, PHP OCI8
linked with Instant Client 11.2 can connect to Oracle Database 9.2
onward. See Oracle's note "Oracle Client / Server Interoperability
Support" (ID 207303.1) for details. PHP OCI8 2.1.0 can be built with
PHP 7. PHP OCI8 2.0.9 can be built with PHP 5.2 onward. Use the older
PHP OCI8 1.4.10 when using PHP 4.3.9 through to PHP 5.1.x, or when
only Oracle Database 9.2 client libraries are available.
Use the OCI8 extension to access Oracle Database. PHP OCI8 2.1 builds
with PHP 7. Use 'pecl install oci8-2.0.10' to install OCI8 for PHP
5.2 - PHP 5.6. Use 'pecl install oci8-1.4.10' to install PHP OCI8 1.4
for PHP 4.3.9 - PHP 5.1. The OCI8 extension can be linked with Oracle
client libraries from Oracle Database 12.1, 11, or 10.2. These
libraries are found in your database installation, or in the free
Oracle Instant Client from
http://www.oracle.com/technetwork/database/features/instant-client/.
Oracle's standard cross-version connectivity applies. For example,
PHP OCI8 linked with Instant Client 11.2 can connect to Oracle
Database 9.2 onward. See Oracle's note "Oracle Client / Server
Interoperability Support" (ID 207303.1) for details.
</description>
<lead>
<name>Christopher Jones</name>
@@ -45,7 +46,7 @@ only Oracle Database 9.2 client libraries are available.
<active>no</active>
</lead>
<date>2015-01-01</date>
<date>2015-12-12</date>
<time>12:00:00</time>
<version>
@@ -80,53 +81,54 @@ Updated driver name format.
<file name="array_bind_014.phpt" role="test" />
<file name="array_bind_bdouble.phpt" role="test" />
<file name="array_bind_bfloat.phpt" role="test" />
<file name="array_bind_date1.phpt" role="test" />
<file name="array_bind_date.phpt" role="test" />
<file name="array_bind_float1.phpt" role="test" />
<file name="array_bind_date1.phpt" role="test" />
<file name="array_bind_float.phpt" role="test" />
<file name="array_bind_int1.phpt" role="test" />
<file name="array_bind_float1.phpt" role="test" />
<file name="array_bind_int.phpt" role="test" />
<file name="array_bind_str1.phpt" role="test" />
<file name="array_bind_int1.phpt" role="test" />
<file name="array_bind_str.phpt" role="test" />
<file name="array_bind_str1.phpt" role="test" />
<file name="array_bind_uin.phpt" role="test" />
<file name="b47243_1.phpt" role="test" />
<file name="b47243_2.phpt" role="test" />
<file name="b47243_3.phpt" role="test" />
<file name="bind_boolean_1.phpt" role="test" />
<file name="bind_char_1_11gR1.phpt" role="test" />
<file name="bind_char_1.phpt" role="test" />
<file name="bind_char_2_11gR1.phpt" role="test" />
<file name="bind_char_1_11gR1.phpt" role="test" />
<file name="bind_char_2.phpt" role="test" />
<file name="bind_char_3_11gR1.phpt" role="test" />
<file name="bind_char_2_11gR1.phpt" role="test" />
<file name="bind_char_3.phpt" role="test" />
<file name="bind_char_4_11gR1.phpt" role="test" />
<file name="bind_char_3_11gR1.phpt" role="test" />
<file name="bind_char_4.phpt" role="test" />
<file name="bind_char_4_11gR1.phpt" role="test" />
<file name="bind_empty.phpt" role="test" />
<file name="bind_long.phpt" role="test" />
<file name="bind_long_raw.phpt" role="test" />
<file name="bind_misccoltypes_errs.phpt" role="test" />
<file name="bind_misccoltypes.phpt" role="test" />
<file name="bind_misccoltypes_errs.phpt" role="test" />
<file name="bind_number.phpt" role="test" />
<file name="bind_query.phpt" role="test" />
<file name="bind_raw_2.phpt" role="test" />
<file name="bind_raw.phpt" role="test" />
<file name="bind_raw_2.phpt" role="test" />
<file name="bind_rowid.phpt" role="test" />
<file name="bind_sqltafc.phpt" role="test" />
<file name="bind_sqltchr_1.phpt" role="test" />
<file name="bind_sqltchr_2.phpt" role="test" />
<file name="bind_sqltint.phpt" role="test" />
<file name="bind_sqltnum.phpt" role="test" />
<file name="bind_sqltnum_11g.phpt" role="test" />
<file name="bind_unsupported_1.phpt" role="test" />
<file name="bind_unsupported_2.phpt" role="test" />
<file name="bind_unsupported_3.phpt" role="test" />
<file name="bug26133.phpt" role="test" />
<file name="bug27303_1_11gR1.phpt" role="test" />
<file name="bug27303_1.phpt" role="test" />
<file name="bug27303_2_11gR1.phpt" role="test" />
<file name="bug27303_1_11gR1.phpt" role="test" />
<file name="bug27303_2.phpt" role="test" />
<file name="bug27303_2_11gR1.phpt" role="test" />
<file name="bug27303_3.phpt" role="test" />
<file name="bug27303_4_11gR1.phpt" role="test" />
<file name="bug27303_4.phpt" role="test" />
<file name="bug27303_4_11gR1.phpt" role="test" />
<file name="bug32325.phpt" role="test" />
<file name="bug35973.phpt" role="test" />
<file name="bug36010.phpt" role="test" />
@@ -144,8 +146,8 @@ Updated driver name format.
<file name="bug42496_1.phpt" role="test" />
<file name="bug42496_2.phpt" role="test" />
<file name="bug42841.phpt" role="test" />
<file name="bug43492_2.phpt" role="test" />
<file name="bug43492.phpt" role="test" />
<file name="bug43492_2.phpt" role="test" />
<file name="bug43497.phpt" role="test" />
<file name="bug44008.phpt" role="test" />
<file name="bug44113.phpt" role="test" />
@@ -158,54 +160,55 @@ Updated driver name format.
<file name="bug51253.phpt" role="test" />
<file name="bug51291_1.phpt" role="test" />
<file name="bug51291_2.phpt" role="test" />
<file name="bug68298.phpt" role="test" />
<file name="clientversion.phpt" role="test" />
<file name="close.phpt" role="test" />
<file name="coll_001.phpt" role="test" />
<file name="coll_002_func.phpt" role="test" />
<file name="coll_002.phpt" role="test" />
<file name="coll_003_func.phpt" role="test" />
<file name="coll_002_func.phpt" role="test" />
<file name="coll_003.phpt" role="test" />
<file name="coll_004_func.phpt" role="test" />
<file name="coll_003_func.phpt" role="test" />
<file name="coll_004.phpt" role="test" />
<file name="coll_004_func.phpt" role="test" />
<file name="coll_005.phpt" role="test" />
<file name="coll_006_func.phpt" role="test" />
<file name="coll_006.phpt" role="test" />
<file name="coll_006_func.phpt" role="test" />
<file name="coll_007.phpt" role="test" />
<file name="coll_008.phpt" role="test" />
<file name="coll_009_func.phpt" role="test" />
<file name="coll_009.phpt" role="test" />
<file name="coll_010_func.phpt" role="test" />
<file name="coll_009_func.phpt" role="test" />
<file name="coll_010.phpt" role="test" />
<file name="coll_011_func.phpt" role="test" />
<file name="coll_010_func.phpt" role="test" />
<file name="coll_011.phpt" role="test" />
<file name="coll_012_func.phpt" role="test" />
<file name="coll_011_func.phpt" role="test" />
<file name="coll_012.phpt" role="test" />
<file name="coll_013_func.phpt" role="test" />
<file name="coll_012_func.phpt" role="test" />
<file name="coll_013.phpt" role="test" />
<file name="coll_014_func.phpt" role="test" />
<file name="coll_013_func.phpt" role="test" />
<file name="coll_014.phpt" role="test" />
<file name="coll_015_func.phpt" role="test" />
<file name="coll_014_func.phpt" role="test" />
<file name="coll_015.phpt" role="test" />
<file name="coll_016_func.phpt" role="test" />
<file name="coll_015_func.phpt" role="test" />
<file name="coll_016.phpt" role="test" />
<file name="coll_017_func.phpt" role="test" />
<file name="coll_016_func.phpt" role="test" />
<file name="coll_017.phpt" role="test" />
<file name="coll_017_func.phpt" role="test" />
<file name="coll_018.phpt" role="test" />
<file name="coll_019.phpt" role="test" />
<file name="commit_001.phpt" role="test" />
<file name="commit_002.phpt" role="test" />
<file name="commit_old.phpt" role="test" />
<file name="conn_attr.inc" role="test" />
<file name="conn_attr_1.phpt" role="test" />
<file name="conn_attr_2.phpt" role="test" />
<file name="conn_attr_3.phpt" role="test" />
<file name="conn_attr_4.phpt" role="test" />
<file name="conn_attr_5.phpt" role="test" />
<file name="conn_attr.inc" role="test" />
<file name="connect_1_old.phpt" role="test" />
<file name="connect_1.phpt" role="test" />
<file name="connect.inc" role="test" />
<file name="connect_old.phpt" role="test" />
<file name="connect.phpt" role="test" />
<file name="connect_1.phpt" role="test" />
<file name="connect_1_old.phpt" role="test" />
<file name="connect_old.phpt" role="test" />
<file name="connect_scope1.phpt" role="test" />
<file name="connect_scope2.phpt" role="test" />
<file name="connect_scope_try1.phpt" role="test" />
@@ -215,24 +218,25 @@ Updated driver name format.
<file name="connect_scope_try5.phpt" role="test" />
<file name="connect_scope_try6.phpt" role="test" />
<file name="connect_with_charset_001.phpt" role="test" />
<file name="connect_without_oracle_home_11.phpt" role="test" />
<file name="connect_without_oracle_home_old_11.phpt" role="test" />
<file name="connect_without_oracle_home_old.phpt" role="test" />
<file name="connect_without_oracle_home.phpt" role="test" />
<file name="connect_without_oracle_home_11.phpt" role="test" />
<file name="connect_without_oracle_home_old.phpt" role="test" />
<file name="connect_without_oracle_home_old_11.phpt" role="test" />
<file name="create_table.inc" role="test" />
<file name="create_type.inc" role="test" />
<file name="cursor_bind_err.phpt" role="test" />
<file name="cursor_bind.phpt" role="test" />
<file name="cursors_old.phpt" role="test" />
<file name="cursor_bind_err.phpt" role="test" />
<file name="cursors.phpt" role="test" />
<file name="dbmsoutput.phpt" role="test" />
<file name="cursors_old.phpt" role="test" />
<file name="db_op_1.phpt" role="test" />
<file name="db_op_2.phpt" role="test" />
<file name="dbmsoutput.phpt" role="test" />
<file name="debug.phpt" role="test" />
<file name="default_prefetch.phpt" role="test" />
<file name="default_prefetch0.phpt" role="test" />
<file name="default_prefetch1.phpt" role="test" />
<file name="default_prefetch2.phpt" role="test" />
<file name="default_prefetch.phpt" role="test" />
<file name="define.phpt" role="test" />
<file name="define0.phpt" role="test" />
<file name="define1.phpt" role="test" />
<file name="define2.phpt" role="test" />
@@ -241,7 +245,6 @@ Updated driver name format.
<file name="define5.phpt" role="test" />
<file name="define6.phpt" role="test" />
<file name="define_old.phpt" role="test" />
<file name="define.phpt" role="test" />
<file name="descriptors.phpt" role="test" />
<file name="details.inc" role="test" />
<file name="drcp_cclass1.phpt" role="test" />
@@ -261,11 +264,13 @@ Updated driver name format.
<file name="drcp_scope4.phpt" role="test" />
<file name="drcp_scope5.phpt" role="test" />
<file name="driver_name.phpt" role="test" />
<file name="driver_name_11gR2.phpt" role="test" />
<file name="drop_table.inc" role="test" />
<file name="drop_type.inc" role="test" />
<file name="dupcolnames.phpt" role="test" />
<file name="edition_1.phpt" role="test" />
<file name="edition_2.phpt" role="test" />
<file name="error.phpt" role="test" />
<file name="error1.phpt" role="test" />
<file name="error2.phpt" role="test" />
<file name="error3.phpt" role="test" />
@@ -274,7 +279,6 @@ Updated driver name format.
<file name="error_bind_3.phpt" role="test" />
<file name="error_old.phpt" role="test" />
<file name="error_parse.phpt" role="test" />
<file name="error.phpt" role="test" />
<file name="error_set.phpt" role="test" />
<file name="exec_fetch.phpt" role="test" />
<file name="execute_mode.phpt" role="test" />
@@ -282,28 +286,28 @@ Updated driver name format.
<file name="extauth_02.phpt" role="test" />
<file name="extauth_03.phpt" role="test" />
<file name="extauth_04.phpt" role="test" />
<file name="fetch.phpt" role="test" />
<file name="fetch_all.phpt" role="test" />
<file name="fetch_all1.phpt" role="test" />
<file name="fetch_all2.phpt" role="test" />
<file name="fetch_all3.phpt" role="test" />
<file name="fetch_all4.phpt" role="test" />
<file name="fetch_all5.phpt" role="test" />
<file name="fetch_all.phpt" role="test" />
<file name="fetch_array.phpt" role="test" />
<file name="fetch_assoc.phpt" role="test" />
<file name="fetch_into.phpt" role="test" />
<file name="fetch_into1.phpt" role="test" />
<file name="fetch_into2.phpt" role="test" />
<file name="fetch_into.phpt" role="test" />
<file name="fetch_object.phpt" role="test" />
<file name="fetch_object_1.phpt" role="test" />
<file name="fetch_object_2.phpt" role="test" />
<file name="fetch_object.phpt" role="test" />
<file name="fetch.phpt" role="test" />
<file name="fetch_row.phpt" role="test" />
<file name="field_funcs.phpt" role="test" />
<file name="field_funcs0.phpt" role="test" />
<file name="field_funcs1.phpt" role="test" />
<file name="field_funcs2.phpt" role="test" />
<file name="field_funcs3.phpt" role="test" />
<file name="field_funcs_old.phpt" role="test" />
<file name="field_funcs.phpt" role="test" />
<file name="function_aliases.phpt" role="test" />
<file name="imp_res_1.phpt" role="test" />
<file name="imp_res_2.phpt" role="test" />
@@ -384,33 +388,33 @@ Updated driver name format.
<file name="lob_044.phpt" role="test" />
<file name="lob_aliases.phpt" role="test" />
<file name="lob_null.phpt" role="test" />
<file name="lob_temp.phpt" role="test" />
<file name="lob_temp1.phpt" role="test" />
<file name="lob_temp2.phpt" role="test" />
<file name="lob_temp.phpt" role="test" />
<file name="minfo.phpt" role="test" />
<file name="null_byte_1.phpt" role="test" />
<file name="null_byte_2.phpt" role="test" />
<file name="null_byte_3.phpt" role="test" />
<file name="num.phpt" role="test" />
<file name="oci_execute_segfault.phpt" role="test" />
<file name="old_oci_close1.phpt" role="test" />
<file name="old_oci_close.phpt" role="test" />
<file name="old_oci_close1.phpt" role="test" />
<file name="password.phpt" role="test" />
<file name="password_2.phpt" role="test" />
<file name="password_new.phpt" role="test" />
<file name="password_old.phpt" role="test" />
<file name="password.phpt" role="test" />
<file name="pecl_bug10194_blob_64.phpt" role="test" />
<file name="pecl_bug10194_blob.phpt" role="test" />
<file name="pecl_bug10194.phpt" role="test" />
<file name="pecl_bug10194_blob.phpt" role="test" />
<file name="pecl_bug10194_blob_64.phpt" role="test" />
<file name="pecl_bug16035.phpt" role="test" />
<file name="pecl_bug16842.phpt" role="test" />
<file name="pecl_bug6109.phpt" role="test" />
<file name="pecl_bug8816.phpt" role="test" />
<file name="persistent.phpt" role="test" />
<file name="prefetch_old.phpt" role="test" />
<file name="prefetch.phpt" role="test" />
<file name="privileged_connect1.phpt" role="test" />
<file name="prefetch_old.phpt" role="test" />
<file name="privileged_connect.phpt" role="test" />
<file name="privileged_connect1.phpt" role="test" />
<file name="refcur_prefetch_1.phpt" role="test" />
<file name="refcur_prefetch_2.phpt" role="test" />
<file name="refcur_prefetch_3.phpt" role="test" />
@@ -421,11 +425,11 @@ Updated driver name format.
<file name="serverversion.phpt" role="test" />
<file name="skipif.inc" role="test" />
<file name="statement_cache.phpt" role="test" />
<file name="statement_type_old.phpt" role="test" />
<file name="statement_type.phpt" role="test" />
<file name="statement_type_old.phpt" role="test" />
<file name="test.gif" role="test" />
<file name="testping.phpt" role="test" />
<file name="test.txt" role="test" />
<file name="testping.phpt" role="test" />
<file name="uncommitted.phpt" role="test" />
<file name="xmltype_01.phpt" role="test" />
<file name="xmltype_02.phpt" role="test" />
@@ -448,7 +452,7 @@ Updated driver name format.
<dependencies>
<required>
<php>
<min>5.2.0</min>
<min>7.0.0</min>
</php>
<pearinstaller>
<min>1.4.0b1</min>
+57 -41
View File
@@ -30,8 +30,6 @@
#include "zend_cfg.h"
#include "zend_dump.h"
#define DEBUG_BLOCKPASS 0
/* Checks if a constant (like "true") may be replaced by its value */
int zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy)
{
@@ -129,8 +127,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
/* remove leading NOPs */
strip_leading_nops(op_array, block);
/* we track data dependencies only insight a single basic block */
memset(Tsource, 0, (op_array->last_var + op_array->T) * sizeof(zend_op *));
opline = op_array->opcodes + block->start;
end = op_array->opcodes + block->end + 1;
while (opline < end) {
@@ -326,9 +322,17 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
}
#endif
case ZEND_FETCH_LIST:
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
/* LIST variable will be deleted later by FREE */
Tsource[VAR_NUM(opline->op1.var)] = NULL;
}
break;
case ZEND_CASE:
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
/* CASE variable will be deleted later by FREE, so we can't optimize it */
Tsource[VAR_NUM(opline->op1.var)] = NULL;
break;
}
if (opline->op1_type == IS_CONST &&
@@ -759,9 +763,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
zend_op *new_opcodes;
zend_op *opline;
uint32_t len = 0;
#if DEBUG_BLOCKPASS
int n;
#endif
for (b = blocks; b < end; b++) {
if (b->flags & ZEND_BB_REACHABLE) {
@@ -776,7 +778,11 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
if (next < end && next == blocks + b->successors[0]) {
/* JMP to the next block - strip it */
MAKE_NOP(opline);
b->end--;
if (b->end == 0) {
b->start++;
} else {
b->end--;
}
}
} else if (b->start == b->end && opline->opcode == ZEND_NOP) {
/* skip empty block */
@@ -811,6 +817,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
b->end = opline - new_opcodes + n - 1;
opline += n;
} else {
b->flags |= ZEND_BB_EMPTY;
b->start = b->end = opline - new_opcodes;
}
}
@@ -822,7 +829,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
op_array->last = len;
for (b = blocks; b < end; b++) {
if (!(b->flags & ZEND_BB_REACHABLE)) {
if (!(b->flags & ZEND_BB_REACHABLE) || b->start > b->end) {
continue;
}
opline = op_array->opcodes + b->end;
@@ -948,8 +955,8 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
op_array->last_live_range = j;
while (opline != end) {
if ((opline->opcode == ZEND_FREE || opline->opcode == ZEND_FE_FREE) &&
opline->extended_value == ZEND_FREE_ON_RETURN &&
opline->op2.num < (uint32_t)j) {
opline->extended_value == ZEND_FREE_ON_RETURN) {
ZEND_ASSERT(opline->op2.num < (uint32_t) i);
opline->op2.num = map[opline->op2.num];
}
opline++;
@@ -975,15 +982,13 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
*opline_num = -1;
}
#if DEBUG_BLOCKPASS
/* rebild map (judt for printing) */
/* rebuild map (just for printing) */
memset(cfg->map, -1, sizeof(int) * op_array->last);
for (n = 0; n < cfg->blocks_count; n++) {
if (cfg->blocks[n].flags & ZEND_BB_REACHABLE) {
cfg->map[cfg->blocks[n].start] = n;
}
}
#endif
}
static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_array, zend_cfg *cfg, zend_uchar *same_t)
@@ -1460,7 +1465,7 @@ next_target_znz:
static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset used_ext, zend_optimizer_ctx *ctx)
{
int n;
zend_basic_block *block;
zend_basic_block *block, *next_block;
uint32_t var_num;
uint32_t bitset_len;
zend_bitset usage;
@@ -1476,9 +1481,9 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
checkpoint = zend_arena_checkpoint(ctx->arena);
bitset_len = zend_bitset_len(op_array->last_var + op_array->T);
usage = zend_arena_calloc(&ctx->arena, bitset_len, ZEND_BITSET_ELM_SIZE);
defined_here = zend_arena_alloc(&ctx->arena, bitset_len * ZEND_BITSET_ELM_SIZE);
zend_bitset_clear(defined_here, bitset_len);
for (n = 1; n < cfg->blocks_count; n++) {
block = cfg->blocks + n;
@@ -1488,7 +1493,11 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
opline = op_array->opcodes + block->start;
end = op_array->opcodes + block->end + 1;
zend_bitset_clear(defined_here, bitset_len);
if (!(block->flags & ZEND_BB_FOLLOW) ||
(block->flags & ZEND_BB_TARGET)) {
/* Skip continuation of "extended" BB */
zend_bitset_clear(defined_here, bitset_len);
}
while (opline<end) {
if (opline->op1_type == IS_VAR || opline->op1_type == IS_TMP_VAR) {
@@ -1534,15 +1543,14 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
}
}
#if DEBUG_BLOCKPASS > 2
{
if (ctx->debug_level & ZEND_DUMP_BLOCK_PASS_VARS) {
int printed = 0;
uint32_t i;
for (i = op_array->last_var; i< op_array->T; i++) {
if (zend_bitset_in(used_ext, i)) {
if (!printed) {
fprintf(stderr, "NON-LOCAL-VARS: %s: %d", op_array->function_name ? op_array->function_name->val : "(null)", i);
fprintf(stderr, "NON-LOCAL-VARS: %d", i);
printed = 1;
} else {
fprintf(stderr, ", %d", i);
@@ -1551,13 +1559,13 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
}
if (printed) {
fprintf(stderr, "\n");
zend_dump_op_array(op_array, cfg, 0);
}
}
#endif
for (n = 0; n < cfg->blocks_count; n++) {
block = cfg->blocks + n;
usage = defined_here;
next_block = NULL;
for (n = cfg->blocks_count; n > 0;) {
block = cfg->blocks + (--n);
if (!(block->flags & ZEND_BB_REACHABLE)) {
continue;
@@ -1565,7 +1573,15 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
opline = op_array->opcodes + block->end;
end = op_array->opcodes + block->start;
zend_bitset_copy(usage, used_ext, bitset_len);
if (!next_block ||
!(next_block->flags & ZEND_BB_FOLLOW) ||
(next_block->flags & ZEND_BB_TARGET)) {
/* Skip continuation of "extended" BB */
zend_bitset_copy(usage, used_ext, bitset_len);
} else if (block->successors[1] != -1) {
zend_bitset_union(usage, used_ext, bitset_len);
}
next_block = block;
while (opline >= end) {
/* usage checks */
@@ -1727,22 +1743,16 @@ void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
zend_op **Tsource;
zend_uchar *same_t;
#if DEBUG_BLOCKPASS
fprintf(stderr, "File %s func %s\n", op_array->filename->val, op_array->function_name ? op_array->function_name->val : "main");
fflush(stderr);
#endif
/* Build CFG */
checkpoint = zend_arena_checkpoint(ctx->arena);
if (zend_build_cfg(&ctx->arena, op_array, 0, 0, &cfg, NULL) != SUCCESS) {
if (zend_build_cfg(&ctx->arena, op_array, 0, &cfg, NULL) != SUCCESS) {
zend_arena_release(&ctx->arena, checkpoint);
return;
}
#if DEBUG_BLOCKPASS
fprintf(stderr, "\nBEFORE-BLOCK-PASS: %s:\n", op_array->function_name ? op_array->function_name->val : "(null)");
zend_dump_op_array(op_array, &cfg, 1);
#endif
if (ctx->debug_level & ZEND_DUMP_BEFORE_BLOCK_PASS) {
zend_dump_op_array(op_array, ZEND_DUMP_CFG, "before block pass", &cfg);
}
if (op_array->last_var || op_array->T) {
bitset_len = zend_bitset_len(op_array->last_var + op_array->T);
@@ -1764,9 +1774,16 @@ void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
/* optimize each basic block separately */
for (b = blocks; b < end; b++) {
if (b->flags & ZEND_BB_REACHABLE) {
zend_optimize_block(b, op_array, usage, &cfg, Tsource);
if (!(b->flags & ZEND_BB_REACHABLE)) {
continue;
}
/* we track data dependencies only insight a single basic block */
if (!(b->flags & ZEND_BB_FOLLOW) ||
(b->flags & ZEND_BB_TARGET)) {
/* Skip continuation of "extended" BB */
memset(Tsource, 0, (op_array->last_var + op_array->T) * sizeof(zend_op *));
}
zend_optimize_block(b, op_array, usage, &cfg, Tsource);
}
/* Jump optimization for each block */
@@ -1777,7 +1794,7 @@ void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
}
/* Eliminate unreachable basic blocks */
zend_remark_reachable_blocks(op_array, &cfg);
zend_cfg_remark_reachable_blocks(op_array, &cfg);
/* Merge Blocks */
zend_merge_blocks(op_array, &cfg);
@@ -1787,10 +1804,9 @@ void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
zend_t_usage(&cfg, op_array, usage, ctx);
assemble_code_blocks(&cfg, op_array);
#if DEBUG_BLOCKPASS
fprintf(stderr, "\nAFTER-BLOCK-PASS: %s:\n", op_array->function_name ? op_array->function_name->val : "(null)");
zend_dump_op_array(op_array, &cfg, 0);
#endif
if (ctx->debug_level & ZEND_DUMP_AFTER_BLOCK_PASS) {
zend_dump_op_array(op_array, ZEND_DUMP_CFG | ZEND_DUMP_HIDE_UNREACHABLE, "after block pass", &cfg);
}
/* Destroy CFG */
zend_arena_release(&ctx->arena, checkpoint);
+202
View File
@@ -0,0 +1,202 @@
/*
+----------------------------------------------------------------------+
| Zend OPcache |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2015 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
#include "php.h"
#include "Optimizer/zend_optimizer.h"
#include "Optimizer/zend_optimizer_internal.h"
#include "zend_API.h"
#include "zend_constants.h"
#include "zend_execute.h"
#include "zend_vm.h"
#include "zend_bitset.h"
#include "zend_cfg.h"
#include "zend_ssa.h"
#include "zend_func_info.h"
#include "zend_inference.h"
#include "zend_dump.h"
#ifndef HAVE_DFA_PASS
# define HAVE_DFA_PASS 0
#endif
void optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
void *checkpoint;
uint32_t build_flags;
uint32_t flags = 0;
zend_ssa ssa;
#if !HAVE_DFA_PASS
return;
#endif
/* Build SSA */
memset(&ssa, 0, sizeof(ssa));
checkpoint = zend_arena_checkpoint(ctx->arena);
if (zend_build_cfg(&ctx->arena, op_array, 0, &ssa.cfg, &flags) != SUCCESS) {
zend_arena_release(&ctx->arena, checkpoint);
return;
}
if (flags & ZEND_FUNC_TOO_DYNAMIC) {
zend_arena_release(&ctx->arena, checkpoint);
return;
}
if (zend_cfg_build_predecessors(&ctx->arena, &ssa.cfg) != SUCCESS) {
zend_arena_release(&ctx->arena, checkpoint);
return;
}
if (ctx->debug_level & ZEND_DUMP_DFA_CFG) {
zend_dump_op_array(op_array, ZEND_DUMP_CFG | ZEND_DUMP_HIDE_UNUSED_VARS, "dfa cfg", &ssa.cfg);
}
/* Compute Dominators Tree */
if (zend_cfg_compute_dominators_tree(op_array, &ssa.cfg) != SUCCESS) {
zend_arena_release(&ctx->arena, checkpoint);
return;
}
/* Identify reducible and irreducible loops */
if (zend_cfg_identify_loops(op_array, &ssa.cfg, &flags) != SUCCESS) {
zend_arena_release(&ctx->arena, checkpoint);
return;
}
if (ctx->debug_level & ZEND_DUMP_DFA_DOMINATORS) {
zend_dump_dominators(op_array, &ssa.cfg);
}
build_flags = 0;
if (ctx->debug_level & ZEND_DUMP_DFA_LIVENESS) {
build_flags |= ZEND_SSA_DEBUG_LIVENESS;
}
if (ctx->debug_level & ZEND_DUMP_DFA_PHI) {
build_flags |= ZEND_SSA_DEBUG_PHI_PLACEMENT;
}
if (zend_build_ssa(&ctx->arena, op_array, build_flags, &ssa, &flags) != SUCCESS) {
zend_arena_release(&ctx->arena, checkpoint);
return;
}
if (ctx->debug_level & ZEND_DUMP_DFA_SSA) {
zend_dump_op_array(op_array, ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS, "before dfa pass", &ssa);
}
if (zend_ssa_compute_use_def_chains(&ctx->arena, op_array, &ssa) != SUCCESS){
zend_arena_release(&ctx->arena, checkpoint);
return;
}
if (zend_ssa_find_false_dependencies(op_array, &ssa) != SUCCESS) {
zend_arena_release(&ctx->arena, checkpoint);
return;
}
if (zend_ssa_find_sccs(op_array, &ssa) != SUCCESS){
zend_arena_release(&ctx->arena, checkpoint);
return;
}
if (zend_ssa_inference(&ctx->arena, op_array, ctx->script, &ssa) != SUCCESS) {
return;
}
if (ctx->debug_level & ZEND_DUMP_DFA_SSA_VARS) {
zend_dump_ssa_variables(op_array, &ssa);
}
if (ctx->debug_level & ZEND_DUMP_BEFORE_DFA_PASS) {
zend_dump_op_array(op_array, ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS, "before dfa pass", &ssa);
}
//TODO: Add optimization patterns ???
if (ssa.var_info) {
int i;
// 1: #1.T = OP_Y | #3.CV = OP_Y
// 2: ASSIGN #2.CV [undef,null,bool] -> #3.cv, #1.T | NOP
for (i = 0; i < ssa.vars_count; i++) {
int op2 = ssa.vars[i].definition;
if (op2 >= 0
&& op_array->opcodes[op2].opcode == ZEND_ASSIGN
&& op_array->opcodes[op2].op1_type == IS_CV
&& (op_array->opcodes[op2].op2_type & (IS_TMP_VAR|IS_VAR))
&& !RETURN_VALUE_USED(&op_array->opcodes[op2])
) {
int var1 = ssa.ops[op2].op2_use;
int var2 = ssa.ops[op2].op1_use;
if (var1 >= 0
&& var2 >= 0
&& !(ssa.var_info[var2].type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))
&& !(ssa.var_info[var1].type & MAY_BE_REF)
&& ssa.vars[var1].definition >= 0
&& ssa.ops[ssa.vars[var1].definition].result_def == var1
&& ssa.ops[ssa.vars[var1].definition].result_use < 0
&& ssa.vars[var1].use_chain == op2
&& ssa.ops[op2].op2_use_chain < 0
&& !ssa.vars[var1].phi_use_chain
&& !ssa.vars[var1].sym_use_chain
) {
int op1 = ssa.vars[var1].definition;
int var3 = i;
if (zend_ssa_unlink_use_chain(&ssa, op2, var2)) {
/* Reconstruct SSA */
ssa.vars[var3].definition = op1;
ssa.ops[op1].result_def = var3;
ssa.vars[var1].definition = -1;
ssa.vars[var1].use_chain = -1;
ssa.ops[op2].op1_use = -1;
ssa.ops[op2].op2_use = -1;
ssa.ops[op2].op1_def = -1;
ssa.ops[op2].op1_use_chain = -1;
/* Update opcodes */
op_array->opcodes[op1].result_type = op_array->opcodes[op2].op1_type;
op_array->opcodes[op1].result.var = op_array->opcodes[op2].op1.var;
MAKE_NOP(&op_array->opcodes[op2]);
}
}
}
}
}
if (ctx->debug_level & ZEND_DUMP_AFTER_DFA_PASS) {
zend_dump_op_array(op_array, ZEND_DUMP_SSA | ZEND_DUMP_HIDE_UNUSED_VARS, "after dfa pass", &ssa);
}
/* Destroy SSA */
zend_arena_release(&ctx->arena, checkpoint);
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
+3 -1
View File
@@ -42,7 +42,9 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
int i = 0;
zend_op *opline = op_array->opcodes;
zend_op *end = opline + op_array->last;
zend_bool collect_constants = (op_array == &ctx->script->main_op_array);
/* bug #71127*
zend_bool collect_constants = (op_array == &ctx->script->main_op_array); */
zend_bool collect_constants = 0;
while (opline < end) {
switch (opline->opcode) {
+10 -3
View File
@@ -114,14 +114,21 @@ void zend_optimizer_pass2(zend_op_array *op_array)
case ZEND_JMPZ_EX:
case ZEND_JMPNZ_EX:
/* convert Ti = JMPZ_EX(Ti, L) to JMPZ(Ti, L) */
if (0 && /* FIXME: temporary disable unsafe pattern */
ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
#if 0
/* Disabled unsafe pattern: in conjunction with
* ZEND_VM_SMART_BRANCH() this may improperly eliminate
* assignment to Ti.
*/
if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
ZEND_RESULT_TYPE(opline) == IS_TMP_VAR &&
ZEND_OP1(opline).var == ZEND_RESULT(opline).var) {
opline->opcode -= 3;
SET_UNUSED(opline->result);
} else
#endif
/* convert Ti = JMPZ_EX(C, L) => Ti = QM_ASSIGN(C)
in case we know it wouldn't jump */
} else if (ZEND_OP1_TYPE(opline) == IS_CONST) {
if (ZEND_OP1_TYPE(opline) == IS_CONST) {
int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline));
if (opline->opcode == ZEND_JMPZ_EX) {
should_jmp = !should_jmp;
+3 -1
View File
@@ -106,7 +106,9 @@ void zend_optimizer_pass3(zend_op_array *op_array)
zend_uchar tmp_type = opline->op1_type;
znode_op tmp = opline->op1;
if (opline->opcode != ZEND_ADD || ZEND_OP1_TYPE(opline) == IS_CONST) {
if (opline->opcode != ZEND_ADD
|| (ZEND_OP1_TYPE(opline) == IS_CONST
&& Z_TYPE(ZEND_OP1_LITERAL(opline)) != IS_ARRAY)) {
/* protection from array add: $a = array + $a is not commutative! */
COPY_NODE(opline->op1, opline->op2);
COPY_NODE(opline->op2, tmp);
+307
View File
@@ -0,0 +1,307 @@
/*
+----------------------------------------------------------------------+
| Zend Engine, Call Graph |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2015 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
/* $Id:$ */
#include "php.h"
#include "zend_compile.h"
#include "zend_extensions.h"
#include "zend_inference.h"
#include "zend_call_graph.h"
#include "zend_func_info.h"
#include "zend_inference.h"
#include "zend_call_graph.h"
typedef int (*zend_op_array_func_t)(zend_call_graph *call_graph, zend_op_array *op_array);
static int zend_op_array_calc(zend_call_graph *call_graph, zend_op_array *op_array)
{
(void) op_array;
call_graph->op_arrays_count++;
return SUCCESS;
}
static int zend_op_array_collect(zend_call_graph *call_graph, zend_op_array *op_array)
{
zend_func_info *func_info = call_graph->func_infos + call_graph->op_arrays_count;
ZEND_SET_FUNC_INFO(op_array, func_info);
call_graph->op_arrays[call_graph->op_arrays_count] = op_array;
func_info->num = call_graph->op_arrays_count;
func_info->num_args = -1;
func_info->return_value_used = -1;
call_graph->op_arrays_count++;
return SUCCESS;
}
static int zend_foreach_op_array(zend_call_graph *call_graph, zend_script *script, zend_op_array_func_t func)
{
zend_class_entry *ce;
zend_op_array *op_array;
if (func(call_graph, &script->main_op_array) != SUCCESS) {
return FAILURE;
}
ZEND_HASH_FOREACH_PTR(&script->function_table, op_array) {
if (func(call_graph, op_array) != SUCCESS) {
return FAILURE;
}
} ZEND_HASH_FOREACH_END();
ZEND_HASH_FOREACH_PTR(&script->class_table, ce) {
ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
if (op_array->scope == ce) {
if (func(call_graph, op_array) != SUCCESS) {
return FAILURE;
}
}
} ZEND_HASH_FOREACH_END();
} ZEND_HASH_FOREACH_END();
return SUCCESS;
}
static void zend_collect_args_info(zend_call_info *call_info)
{
zend_op *opline = call_info->caller_init_opline;
zend_op *end = call_info->caller_call_opline;
uint32_t i;
int num;
int level = 0;
ZEND_ASSERT(opline && end);
if (!opline->extended_value) {
return;
}
for (i = 0; i < opline->extended_value; i++) {
call_info->arg_info[i].opline = NULL;
}
while (opline < end) {
opline++;
switch (opline->opcode) {
case ZEND_SEND_VAL:
case ZEND_SEND_VAR:
case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR_EX:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_NO_REF:
num = opline->op2.num;
if (num > 0) {
num--;
}
if (!level) {
call_info->arg_info[num].opline = opline;
}
break;
case ZEND_SEND_ARRAY:
case ZEND_SEND_USER:
case ZEND_SEND_UNPACK:
// ???
break;
case ZEND_INIT_FCALL:
case ZEND_INIT_FCALL_BY_NAME:
case ZEND_INIT_NS_FCALL_BY_NAME:
case ZEND_INIT_DYNAMIC_CALL:
case ZEND_NEW:
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_INIT_USER_CALL:
level++;
break;
case ZEND_DO_FCALL:
case ZEND_DO_ICALL:
case ZEND_DO_UCALL:
case ZEND_DO_FCALL_BY_NAME:
level--;
break;
}
}
}
static int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_op_array *op_array, zend_func_info *func_info)
{
zend_op *opline = op_array->opcodes;
zend_op *end = opline + op_array->last;
zend_function *func;
zend_call_info *call_info;
int call = 0;
zend_call_info **call_stack;
ALLOCA_FLAG(use_heap);
call_stack = do_alloca((op_array->last / 2) * sizeof(zend_call_info*), use_heap);
while (opline != end) {
call_info = NULL;
switch (opline->opcode) {
case ZEND_INIT_FCALL:
if ((func = zend_hash_find_ptr(&script->function_table, Z_STR_P(CRT_CONSTANT(opline->op2)))) != NULL) {
zend_func_info *callee_func_info = ZEND_FUNC_INFO(&func->op_array);
if (callee_func_info) {
call_info = zend_arena_calloc(arena, 1, sizeof(zend_call_info) + (sizeof(zend_send_arg_info) * ((int)opline->extended_value - 1)));
call_info->caller_op_array = op_array;
call_info->caller_init_opline = opline;
call_info->caller_call_opline = NULL;
call_info->callee_func = func;
call_info->num_args = opline->extended_value;
call_info->next_caller = callee_func_info->caller_info;
callee_func_info->caller_info = call_info;
call_info->next_callee = func_info->callee_info;
func_info->callee_info = call_info;
}
} else if ((func = zend_hash_find_ptr(EG(function_table), Z_STR_P(CRT_CONSTANT(opline->op2)))) != NULL &&
func->type == ZEND_INTERNAL_FUNCTION) {
call_info = zend_arena_calloc(arena, 1, sizeof(zend_call_info) + (sizeof(zend_send_arg_info) * ((int)opline->extended_value - 1)));
call_info->caller_op_array = op_array;
call_info->caller_init_opline = opline;
call_info->caller_call_opline = NULL;
call_info->callee_func = func;
call_info->num_args = opline->extended_value;
call_info->next_caller = NULL;
call_info->next_callee = func_info->callee_info;
func_info->callee_info = call_info;
}
/* break missing intentionally */
case ZEND_INIT_FCALL_BY_NAME:
case ZEND_INIT_NS_FCALL_BY_NAME:
case ZEND_INIT_DYNAMIC_CALL:
case ZEND_NEW:
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_INIT_USER_CALL:
call_stack[call] = call_info;
call++;
break;
case ZEND_DO_FCALL:
case ZEND_DO_ICALL:
case ZEND_DO_UCALL:
case ZEND_DO_FCALL_BY_NAME:
func_info->flags |= ZEND_FUNC_HAS_CALLS;
call--;
if (call_stack[call]) {
call_stack[call]->caller_call_opline = opline;
zend_collect_args_info(call_stack[call]);
}
break;
}
opline++;
}
free_alloca(call_stack, use_heap);
return SUCCESS;
}
static int zend_is_indirectly_recursive(zend_op_array *root, zend_op_array *op_array, zend_bitset visited)
{
zend_func_info *func_info;
zend_call_info *call_info;
int ret = 0;
if (op_array == root) {
return 1;
}
func_info = ZEND_FUNC_INFO(op_array);
if (zend_bitset_in(visited, func_info->num)) {
return 0;
}
zend_bitset_incl(visited, func_info->num);
call_info = func_info->caller_info;
while (call_info) {
if (zend_is_indirectly_recursive(root, call_info->caller_op_array, visited)) {
call_info->recursive = 1;
ret = 1;
}
call_info = call_info->next_caller;
}
return ret;
}
static void zend_analyze_recursion(zend_call_graph *call_graph)
{
zend_op_array *op_array;
zend_func_info *func_info;
zend_call_info *call_info;
int i;
int set_len = zend_bitset_len(call_graph->op_arrays_count);
zend_bitset visited;
ALLOCA_FLAG(use_heap);
visited = ZEND_BITSET_ALLOCA(set_len, use_heap);
for (i = 0; i < call_graph->op_arrays_count; i++) {
op_array = call_graph->op_arrays[i];
func_info = call_graph->func_infos + i;
call_info = func_info->caller_info;
while (call_info) {
if (call_info->caller_op_array == op_array) {
call_info->recursive = 1;
func_info->flags |= ZEND_FUNC_RECURSIVE | ZEND_FUNC_RECURSIVE_DIRECTLY;
} else {
memset(visited, 0, sizeof(uint32_t) * set_len);
if (zend_is_indirectly_recursive(op_array, call_info->caller_op_array, visited)) {
call_info->recursive = 1;
func_info->flags |= ZEND_FUNC_RECURSIVE | ZEND_FUNC_RECURSIVE_INDIRECTLY;
}
}
call_info = call_info->next_caller;
}
}
}
static void zend_sort_op_arrays(zend_call_graph *call_graph)
{
(void) call_graph;
// TODO: perform topological sort of cyclic call graph
}
int zend_build_call_graph(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_call_graph *call_graph) /* {{{ */
{
int i;
call_graph->op_arrays_count = 0;
if (zend_foreach_op_array(call_graph, script, zend_op_array_calc) != SUCCESS) {
return FAILURE;
}
call_graph->op_arrays = (zend_op_array**)zend_arena_calloc(arena, call_graph->op_arrays_count, sizeof(zend_op_array*));
call_graph->func_infos = (zend_func_info*)zend_arena_calloc(arena, call_graph->op_arrays_count, sizeof(zend_func_info));
if (!call_graph->op_arrays || !call_graph->func_infos) {
return FAILURE;
}
call_graph->op_arrays_count = 0;
if (zend_foreach_op_array(call_graph, script, zend_op_array_collect) != SUCCESS) {
return FAILURE;
}
for (i = 0; i < call_graph->op_arrays_count; i++) {
zend_analyze_calls(arena, script, build_flags, call_graph->op_arrays[i], call_graph->func_infos + i);
}
zend_analyze_recursion(call_graph);
zend_sort_op_arrays(call_graph);
return SUCCESS;
}
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
+83
View File
@@ -0,0 +1,83 @@
/*
+----------------------------------------------------------------------+
| Zend Engine, Call Graph |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2015 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_CALL_GRAPH_H
#define ZEND_CALL_GRAPH_H
#include "zend_ssa.h"
#include "zend_func_info.h"
#include "zend_optimizer.h"
typedef struct _zend_send_arg_info {
zend_op *opline;
} zend_send_arg_info;
typedef struct _zend_recv_arg_info {
int ssa_var;
zend_ssa_var_info info;
} zend_recv_arg_info;
struct _zend_call_info {
zend_op_array *caller_op_array;
zend_op *caller_init_opline;
zend_op *caller_call_opline;
zend_function *callee_func;
zend_call_info *next_caller;
zend_call_info *next_callee;
zend_func_info *clone;
int recursive;
int num_args;
zend_send_arg_info arg_info[1];
};
struct _zend_func_info {
int num;
uint32_t flags;
zend_ssa ssa; /* Static Single Assignmnt Form */
zend_call_info *caller_info; /* where this function is called from */
zend_call_info *callee_info; /* which functions are called from this one */
int num_args; /* (-1 - unknown) */
zend_recv_arg_info *arg_info;
zend_ssa_var_info return_info;
zend_func_info *clone;
int clone_num;
int return_value_used; /* -1 unknown, 0 no, 1 yes */
void *codegen_data;
};
typedef struct _zend_call_graph {
int op_arrays_count;
zend_op_array **op_arrays;
zend_func_info *func_infos;
} zend_call_graph;
BEGIN_EXTERN_C()
int zend_build_call_graph(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_call_graph *call_graph);
END_EXTERN_C()
#endif /* ZEND_CALL_GRAPH_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
+215 -17
View File
@@ -19,8 +19,10 @@
#include "php.h"
#include "zend_compile.h"
#include "zend_cfg.h"
#include "zend_func_info.h"
#include "zend_worklist.h"
static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend_basic_block *b)
static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend_basic_block *b) /* {{{ */
{
zend_uchar opcode;
zend_basic_block *b0;
@@ -72,8 +74,9 @@ static void zend_mark_reachable(zend_op *opcodes, zend_basic_block *blocks, zend
}
}
}
/* }}} */
static void zend_mark_reachable_blocks(zend_op_array *op_array, zend_cfg *cfg, int start)
static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg, int start) /* {{{ */
{
zend_basic_block *blocks = cfg->blocks;
@@ -195,8 +198,9 @@ static void zend_mark_reachable_blocks(zend_op_array *op_array, zend_cfg *cfg, i
} while (changed);
}
}
/* }}} */
void zend_remark_reachable_blocks(zend_op_array *op_array, zend_cfg *cfg)
void zend_cfg_remark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */
{
zend_basic_block *blocks = cfg->blocks;
int i;
@@ -217,6 +221,7 @@ void zend_remark_reachable_blocks(zend_op_array *op_array, zend_cfg *cfg)
zend_mark_reachable_blocks(op_array, cfg, start);
}
/* }}} */
static void record_successor(zend_basic_block *blocks, int pred, int n, int succ)
{
@@ -228,7 +233,7 @@ static void record_successor(zend_basic_block *blocks, int pred, int n, int succ
block_map[i] = 1; \
} while (0)
int zend_build_cfg(zend_arena **arena, zend_op_array *op_array, int rt_constants, int stackless, zend_cfg *cfg, uint32_t *func_flags) /* {{{ */
int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg, uint32_t *func_flags) /* {{{ */
{
uint32_t flags = 0;
uint32_t i;
@@ -266,7 +271,7 @@ int zend_build_cfg(zend_arena **arena, zend_op_array *op_array, int rt_constants
case ZEND_YIELD:
case ZEND_YIELD_FROM:
flags |= ZEND_FUNC_TOO_DYNAMIC;
if (stackless) {
if (build_flags & ZEND_CFG_STACKLESS) {
BB_START(i + 1);
}
break;
@@ -274,7 +279,7 @@ int zend_build_cfg(zend_arena **arena, zend_op_array *op_array, int rt_constants
case ZEND_DO_UCALL:
case ZEND_DO_FCALL_BY_NAME:
flags |= ZEND_FUNC_HAS_CALLS;
if (stackless) {
if (build_flags & ZEND_CFG_STACKLESS) {
BB_START(i + 1);
}
break;
@@ -282,11 +287,7 @@ int zend_build_cfg(zend_arena **arena, zend_op_array *op_array, int rt_constants
flags |= ZEND_FUNC_HAS_CALLS;
break;
case ZEND_INIT_FCALL:
if (rt_constants) {
zv = RT_CONSTANT(op_array, opline->op2);
} else {
zv = CT_CONSTANT_EX(op_array, opline->op2.constant);
}
zv = CRT_CONSTANT(opline->op2);
if ((fn = zend_hash_find_ptr(EG(function_table), Z_STR_P(zv))) != NULL) {
if (fn->type == ZEND_INTERNAL_FUNCTION) {
if (Z_STRLEN_P(zv) == sizeof("extract")-1 &&
@@ -377,11 +378,7 @@ int zend_build_cfg(zend_arena **arena, zend_op_array *op_array, int rt_constants
case ZEND_DECLARE_LAMBDA_FUNCTION: {
//??? zend_op_array *lambda_op_array;
//???
//??? if (rt_constants) {
//??? zv = RT_CONSTANT(op_array, opline->op1);
//??? } else {
//??? zv = CT_CONSTANT_EX(op_array, opline->op1.constant);
//??? }
//??? zv = CRT_CONSTANT(opline->op1);
//??? if (ctx->main_script &&
//??? (lambda_op_array = zend_hash_find_ptr(&ctx->main_script->function_table, Z_STR_P(zv))) != NULL) {
//??? if (lambda_op_array->type == ZEND_USER_FUNCTION &&
@@ -536,7 +533,7 @@ int zend_build_cfg(zend_arena **arena, zend_op_array *op_array, int rt_constants
zend_mark_reachable_blocks(op_array, cfg, 0);
if (func_flags) {
*func_flags = flags;
*func_flags |= flags;
}
return SUCCESS;
@@ -606,6 +603,207 @@ int zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg) /* {{{ */
}
/* }}} */
int zend_cfg_compute_dominators_tree(const zend_op_array *op_array, zend_cfg *cfg) /* {{{ */
{
zend_basic_block *blocks = cfg->blocks;
int blocks_count = cfg->blocks_count;
int j, k, changed;
/* FIXME: move declarations */
blocks[0].idom = 0;
do {
changed = 0;
for (j = 1; j < blocks_count; j++) {
int idom = -1;
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
continue;
}
for (k = 0; k < blocks[j].predecessors_count; k++) {
int pred = cfg->predecessors[blocks[j].predecessor_offset + k];
if (idom < 0) {
if (blocks[pred].idom >= 0)
idom = pred;
continue;
}
if (blocks[pred].idom >= 0) {
while (idom != pred) {
while (pred > idom) pred = blocks[pred].idom;
while (idom > pred) idom = blocks[idom].idom;
}
}
}
if (idom >= 0 && blocks[j].idom != idom) {
blocks[j].idom = idom;
changed = 1;
}
}
} while (changed);
blocks[0].idom = -1;
for (j = 1; j < blocks_count; j++) {
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
continue;
}
if (blocks[j].idom >= 0) {
/* Sort by block number to traverse children in pre-order */
if (blocks[blocks[j].idom].children < 0 ||
j < blocks[blocks[j].idom].children) {
blocks[j].next_child = blocks[blocks[j].idom].children;
blocks[blocks[j].idom].children = j;
} else {
int k = blocks[blocks[j].idom].children;
while (blocks[k].next_child >=0 && j > blocks[k].next_child) {
k = blocks[k].next_child;
}
blocks[j].next_child = blocks[k].next_child;
blocks[k].next_child = j;
}
}
}
for (j = 0; j < blocks_count; j++) {
int idom = blocks[j].idom, level = 0;
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
continue;
}
while (idom >= 0) {
level++;
if (blocks[idom].level >= 0) {
level += blocks[idom].level;
break;
} else {
idom = blocks[idom].idom;
}
}
blocks[j].level = level;
}
return SUCCESS;
}
/* }}} */
static int dominates(zend_basic_block *blocks, int a, int b) /* {{{ */
{
while (blocks[b].level > blocks[a].level) {
b = blocks[b].idom;
}
return a == b;
}
/* }}} */
int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg, uint32_t *flags) /* {{{ */
{
int i, j, k;
int depth;
zend_basic_block *blocks = cfg->blocks;
int *dj_spanning_tree;
zend_worklist work;
int flag = ZEND_FUNC_NO_LOOPS;
ALLOCA_FLAG(list_use_heap);
ALLOCA_FLAG(tree_use_heap);
ZEND_WORKLIST_ALLOCA(&work, cfg->blocks_count, list_use_heap);
dj_spanning_tree = do_alloca(sizeof(int) * cfg->blocks_count, tree_use_heap);
for (i = 0; i < cfg->blocks_count; i++) {
dj_spanning_tree[i] = -1;
}
zend_worklist_push(&work, 0);
while (zend_worklist_len(&work)) {
next:
i = zend_worklist_peek(&work);
/* Visit blocks immediately dominated by i. */
for (j = blocks[i].children; j >= 0; j = blocks[j].next_child) {
if (zend_worklist_push(&work, j)) {
dj_spanning_tree[j] = i;
goto next;
}
}
/* Visit join edges. */
for (j = 0; j < 2; j++) {
int succ = blocks[i].successors[j];
if (succ < 0) {
continue;
} else if (blocks[succ].idom == i) {
continue;
} else if (zend_worklist_push(&work, succ)) {
dj_spanning_tree[succ] = i;
goto next;
}
}
zend_worklist_pop(&work);
}
/* Identify loops. See Sreedhar et al, "Identifying Loops Using DJ
Graphs". */
for (i = 0, depth = 0; i < cfg->blocks_count; i++) {
if (blocks[i].level > depth) {
depth = blocks[i].level;
}
}
for (; depth >= 0; depth--) {
for (i = 0; i < cfg->blocks_count; i++) {
if (blocks[i].level != depth) {
continue;
}
zend_bitset_clear(work.visited, zend_bitset_len(cfg->blocks_count));
for (j = 0; j < blocks[i].predecessors_count; j++) {
int pred = cfg->predecessors[blocks[i].predecessor_offset + j];
/* A join edge is one for which the predecessor does not
immediately dominate the successor. */
if (blocks[i].idom == pred) {
continue;
}
/* In a loop back-edge (back-join edge), the successor dominates
the predecessor. */
if (dominates(blocks, i, pred)) {
blocks[i].flags |= ZEND_BB_LOOP_HEADER;
flag &= ~ZEND_FUNC_NO_LOOPS;
zend_worklist_push(&work, pred);
} else {
/* Otherwise it's a cross-join edge. See if it's a branch
to an ancestor on the dominator spanning tree. */
int dj_parent = pred;
while (dj_parent >= 0) {
if (dj_parent == i) {
/* An sp-back edge: mark as irreducible. */
blocks[i].flags |= ZEND_BB_IRREDUCIBLE_LOOP;
flag |= ZEND_FUNC_IRREDUCIBLE;
flag &= ~ZEND_FUNC_NO_LOOPS;
break;
} else {
dj_parent = dj_spanning_tree[dj_parent];
}
}
}
}
while (zend_worklist_len(&work)) {
j = zend_worklist_pop(&work);
if (blocks[j].loop_header < 0 && j != i) {
blocks[j].loop_header = i;
for (k = 0; k < blocks[j].predecessors_count; k++) {
zend_worklist_push(&work, cfg->predecessors[blocks[j].predecessor_offset + k]);
}
}
}
}
}
free_alloca(dj_spanning_tree, tree_use_heap);
ZEND_WORKLIST_FREE_ALLOCA(&work, list_use_heap);
*flags |= flag;
return SUCCESS;
}
/* }}} */
/*
* Local variables:
* tab-width: 4
+25 -8
View File
@@ -19,11 +19,6 @@
#ifndef ZEND_CFG_H
#define ZEND_CFG_H
/* func flags */
#define ZEND_FUNC_TOO_DYNAMIC (1<<0)
#define ZEND_FUNC_HAS_CALLS (1<<1)
#define ZEND_FUNC_VARARG (1<<2)
/* zend_basic_bloc.flags */
#define ZEND_BB_START (1<<0) /* fist block */
#define ZEND_BB_FOLLOW (1<<1) /* follows the next block */
@@ -36,6 +31,7 @@
#define ZEND_BB_FINALLY_END (1<<8) /* end of finally block */
#define ZEND_BB_GEN_VAR (1<<9) /* start of live range */
#define ZEND_BB_KILL_VAR (1<<10) /* end of live range */
#define ZEND_BB_EMPTY (1<<11)
#define ZEND_BB_LOOP_HEADER (1<<16)
#define ZEND_BB_IRREDUCIBLE_LOOP (1<<17)
@@ -92,11 +88,32 @@ typedef struct _zend_cfg {
uint32_t *map;
} zend_cfg;
/* Build Flags */
#define ZEND_RT_CONSTANTS (1<<31)
#define ZEND_CFG_STACKLESS (1<<30)
#define ZEND_SSA_DEBUG_LIVENESS (1<<29)
#define ZEND_SSA_DEBUG_PHI_PLACEMENT (1<<28)
#define CRT_CONSTANT_EX(op_array, node, rt_constants) \
((rt_constants) ? \
RT_CONSTANT(op_array, (node)) \
: \
CT_CONSTANT_EX(op_array, (node).constant) \
)
#define CRT_CONSTANT(node) \
CRT_CONSTANT_EX(op_array, node, (build_flags & ZEND_RT_CONSTANTS))
#define RETURN_VALUE_USED(opline) \
(!((opline)->result_type & EXT_TYPE_UNUSED))
BEGIN_EXTERN_C()
int zend_build_cfg(zend_arena **arena, zend_op_array *op_array, int rt_constants, int stackless, zend_cfg *cfg, uint32_t *func_flags);
void zend_remark_reachable_blocks(zend_op_array *op_array, zend_cfg *cfg);
int zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg);
int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg, uint32_t *func_flags);
void zend_cfg_remark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg);
int zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg);
int zend_cfg_compute_dominators_tree(const zend_op_array *op_array, zend_cfg *cfg);
int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg, uint32_t *flags);
END_EXTERN_C()
+236
View File
@@ -0,0 +1,236 @@
/*
+----------------------------------------------------------------------+
| Zend Engine, DFG - Data Flow Graph |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2015 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
#include "php.h"
#include "zend_compile.h"
#include "zend_dfg.h"
int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg *dfg) /* {{{ */
{
int set_size;
zend_basic_block *blocks = cfg->blocks;
int blocks_count = cfg->blocks_count;
zend_bitset tmp, gen, def, use, in, out;
zend_op *opline;
uint32_t k;
int j, changed;
/* FIXME: can we use "gen" instead of "def" for flow analyzing? */
set_size = dfg->size;
tmp = dfg->tmp;
gen = dfg->gen;
def = dfg->def;
use = dfg->use;
in = dfg->in;
out = dfg->out;
/* Collect "gen", "def" and "use" sets */
for (j = 0; j < blocks_count; j++) {
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
continue;
}
for (k = blocks[j].start; k <= blocks[j].end; k++) {
opline = op_array->opcodes + k;
if (opline->opcode != ZEND_OP_DATA) {
zend_op *next = opline + 1;
if (k < blocks[j].end &&
next->opcode == ZEND_OP_DATA) {
if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(next->op1.var))) {
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(next->op1.var));
}
}
if (next->op2_type == IS_CV) {
if (!DFG_ISSET(def, set_size, j,EX_VAR_TO_NUM(next->op2.var))) {
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(next->op2.var));
}
} else if (next->op2_type == IS_VAR ||
next->op2_type == IS_TMP_VAR) {
/* ZEND_ASSIGN_??? use the second operand
of the following OP_DATA instruction as
a temporary variable */
switch (opline->opcode) {
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
break;
default:
if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(next->op2.var))) {
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(next->op2.var));
}
}
}
}
if (opline->op1_type == IS_CV) {
switch (opline->opcode) {
case ZEND_ASSIGN:
case ZEND_ASSIGN_REF:
case ZEND_BIND_GLOBAL:
case ZEND_SEND_VAR_EX:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_NO_REF:
case ZEND_FE_RESET_R:
case ZEND_FE_RESET_RW:
case ZEND_ADD_ARRAY_ELEMENT:
case ZEND_INIT_ARRAY:
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) {
// FIXME: include into "use" to ...?
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
}
DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
case ZEND_ASSIGN_MUL:
case ZEND_ASSIGN_DIV:
case ZEND_ASSIGN_MOD:
case ZEND_ASSIGN_SL:
case ZEND_ASSIGN_SR:
case ZEND_ASSIGN_CONCAT:
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
case ZEND_ASSIGN_POW:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_POST_INC:
case ZEND_POST_DEC:
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_UNSET_DIM:
case ZEND_UNSET_OBJ:
case ZEND_FETCH_DIM_W:
case ZEND_FETCH_DIM_RW:
case ZEND_FETCH_DIM_FUNC_ARG:
case ZEND_FETCH_DIM_UNSET:
case ZEND_FETCH_OBJ_W:
case ZEND_FETCH_OBJ_RW:
case ZEND_FETCH_OBJ_FUNC_ARG:
case ZEND_FETCH_OBJ_UNSET:
DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
default:
if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) {
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
}
}
} else if (opline->op1_type == IS_VAR ||
opline->op1_type == IS_TMP_VAR) {
if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) {
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
}
}
if (opline->op2_type == IS_CV) {
switch (opline->opcode) {
case ZEND_ASSIGN:
case ZEND_ASSIGN_REF:
case ZEND_FE_FETCH_R:
case ZEND_FE_FETCH_RW:
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) {
// FIXME: include into "use" to ...?
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
}
DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
break;
default:
if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) {
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
}
break;
}
} else if (opline->op2_type == IS_VAR ||
opline->op2_type == IS_TMP_VAR) {
if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) {
DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
}
DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
} else {
if (!DFG_ISSET(def, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) {
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var));
}
}
}
if (opline->result_type == IS_CV) {
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->result.var))) {
DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->result.var));
}
DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->result.var));
} else if (opline->result_type == IS_VAR ||
opline->result_type == IS_TMP_VAR) {
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->result.var))) {
DFG_SET(def, set_size, j, EX_VAR_TO_NUM(opline->result.var));
}
DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(opline->result.var));
}
if ((opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) && opline->result_type == IS_TMP_VAR) {
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(next->result.var))) {
DFG_SET(def, set_size, j, EX_VAR_TO_NUM(next->result.var));
}
DFG_SET(gen, set_size, j, EX_VAR_TO_NUM(next->result.var));
}
}
}
}
/* Calculate "in" and "out" sets */
do {
changed = 0;
for (j = 0; j < blocks_count; j++) {
if ((blocks[j].flags & ZEND_BB_REACHABLE) == 0) {
continue;
}
if (blocks[j].successors[0] >= 0) {
zend_bitset_copy(DFG_BITSET(out, set_size, j), DFG_BITSET(in, set_size, blocks[j].successors[0]), set_size);
if (blocks[j].successors[1] >= 0) {
zend_bitset_union(DFG_BITSET(out, set_size, j), DFG_BITSET(in, set_size, blocks[j].successors[1]), set_size);
}
} else {
zend_bitset_clear(DFG_BITSET(out, set_size, j), set_size);
}
zend_bitset_union_with_difference(tmp, DFG_BITSET(use, set_size, j), DFG_BITSET(out, set_size, j), DFG_BITSET(def, set_size, j), set_size);
if (!zend_bitset_equal(DFG_BITSET(in, set_size, j), tmp, set_size)) {
zend_bitset_copy(DFG_BITSET(in, set_size, j), tmp, set_size);
changed = 1;
}
}
} while (changed);
return SUCCESS;
}
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
+59
View File
@@ -0,0 +1,59 @@
/*
+----------------------------------------------------------------------+
| Zend Engine, DFG - Data Flow Graph |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2015 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_DFG_H
#define ZEND_DFG_H
#include "zend_bitset.h"
#include "zend_cfg.h"
typedef struct _zend_dfg {
int vars;
uint32_t size;
zend_bitset tmp;
zend_bitset gen;
zend_bitset def;
zend_bitset use;
zend_bitset in;
zend_bitset out;
} zend_dfg;
#define DFG_BITSET(set, set_size, block_num) \
((set) + ((block_num) * (set_size)))
#define DFG_SET(set, set_size, block_num, var_num) \
zend_bitset_incl(DFG_BITSET(set, set_size, block_num), (var_num))
#define DFG_ISSET(set, set_size, block_num, var_num) \
zend_bitset_in(DFG_BITSET(set, set_size, block_num), (var_num))
BEGIN_EXTERN_C()
int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg *dfg);
END_EXTERN_C()
#endif /* ZEND_DFG_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
File diff suppressed because it is too large Load Diff
+16 -1
View File
@@ -19,9 +19,24 @@
#ifndef ZEND_DUMP_H
#define ZEND_DUMP_H
#include "zend_ssa.h"
#include "zend_dfg.h"
#define ZEND_DUMP_HIDE_UNREACHABLE (1<<0)
#define ZEND_DUMP_HIDE_UNUSED_VARS (1<<1)
#define ZEND_DUMP_CFG (1<<2)
#define ZEND_DUMP_SSA (1<<3)
#define ZEND_DUMP_RT_CONSTANTS ZEND_RT_CONSTANTS
BEGIN_EXTERN_C()
void zend_dump_op_array(const zend_op_array *op_array, const zend_cfg *cfg, int all);
void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, const char *msg, const void *data);
void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg);
void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg);
void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa);
void zend_dump_variables(const zend_op_array *op_array);
void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa);
void zend_dump_var(const zend_op_array *op_array, zend_uchar var_type, int var_num);
END_EXTERN_C()
File diff suppressed because it is too large Load Diff
+70
View File
@@ -0,0 +1,70 @@
/*
+----------------------------------------------------------------------+
| Zend Engine, Func Info |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2015 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_FUNC_INFO_H
#define ZEND_FUNC_INFO_H
#include "zend_ssa.h"
/* func flags */
#define ZEND_FUNC_TOO_DYNAMIC (1<<0)
#define ZEND_FUNC_HAS_CALLS (1<<1)
#define ZEND_FUNC_VARARG (1<<2)
#define ZEND_FUNC_NO_LOOPS (1<<3)
#define ZEND_FUNC_IRREDUCIBLE (1<<4)
#define ZEND_FUNC_RECURSIVE (1<<7)
#define ZEND_FUNC_RECURSIVE_DIRECTLY (1<<8)
#define ZEND_FUNC_RECURSIVE_INDIRECTLY (1<<9)
/* The following flags are valid only for return values of internal functions
* returned by zend_get_func_info()
*/
#define FUNC_MAY_WARN (1<<30)
#define FUNC_MAY_INLINE (1<<31)
typedef struct _zend_func_info zend_func_info;
typedef struct _zend_call_info zend_call_info;
#define ZEND_FUNC_INFO(op_array) \
((zend_func_info*)((op_array)->reserved[zend_func_info_rid]))
#define ZEND_SET_FUNC_INFO(op_array, info) do { \
zend_func_info** pinfo = (zend_func_info**)&(op_array)->reserved[zend_func_info_rid]; \
*pinfo = info; \
} while (0)
BEGIN_EXTERN_C()
extern int zend_func_info_rid;
uint32_t zend_get_func_info(const zend_call_info *call_info, const zend_ssa *ssa);
int zend_func_info_startup(void);
int zend_func_info_shutdown(void);
END_EXTERN_C()
#endif /* ZEND_FUNC_INFO_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
File diff suppressed because it is too large Load Diff
+292
View File
@@ -0,0 +1,292 @@
/*
+----------------------------------------------------------------------+
| Zend Engine, e-SSA based Type & Range Inference |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2015 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_INFERENCE_H
#define ZEND_INFERENCE_H
#include "zend_optimizer.h"
#include "zend_ssa.h"
#include "zend_bitset.h"
/* Bitmask for type inference (zend_ssa_var_info.type) */
#define MAY_BE_UNDEF (1 << IS_UNDEF)
#define MAY_BE_NULL (1 << IS_NULL)
#define MAY_BE_FALSE (1 << IS_FALSE)
#define MAY_BE_TRUE (1 << IS_TRUE)
#define MAY_BE_LONG (1 << IS_LONG)
#define MAY_BE_DOUBLE (1 << IS_DOUBLE)
#define MAY_BE_STRING (1 << IS_STRING)
#define MAY_BE_ARRAY (1 << IS_ARRAY)
#define MAY_BE_OBJECT (1 << IS_OBJECT)
#define MAY_BE_RESOURCE (1 << IS_RESOURCE)
#define MAY_BE_ANY (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)
#define MAY_BE_REF (1 << IS_REFERENCE) /* may be reference */
#define MAY_BE_ARRAY_SHIFT (IS_REFERENCE)
#define MAY_BE_ARRAY_OF_NULL (MAY_BE_NULL << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_FALSE (MAY_BE_FALSE << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_TRUE (MAY_BE_TRUE << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_LONG (MAY_BE_LONG << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_DOUBLE (MAY_BE_DOUBLE << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_STRING (MAY_BE_STRING << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_ARRAY (MAY_BE_ARRAY << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_OBJECT (MAY_BE_OBJECT << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_RESOURCE (MAY_BE_RESOURCE << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_ANY (MAY_BE_ANY << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_OF_REF (MAY_BE_REF << MAY_BE_ARRAY_SHIFT)
#define MAY_BE_ARRAY_KEY_LONG (1<<21)
#define MAY_BE_ARRAY_KEY_STRING (1<<22)
#define MAY_BE_ARRAY_KEY_ANY (MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_KEY_STRING)
#define MAY_BE_ERROR (1<<23)
#define MAY_BE_CLASS (1<<24)
#define MAY_BE_IN_REG (1<<25) /* value allocated in CPU register */
//TODO: remome MAY_BE_DEF, MAY_BE_RC1, MAY_BE_RCN???
#define MAY_BE_DEF (1<<26)
#define MAY_BE_RC1 (1<<27) /* may be non-reference with refcount == 1 */
#define MAY_BE_RCN (1<<28) /* may be non-reference with refcount > 1 */
#define DEFINE_SSA_OP_HAS_RANGE(opN) \
static zend_always_inline long _ssa_##opN##_has_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline) \
{ \
if (opline->opN##_type == IS_CONST) { \
zval *zv = CRT_CONSTANT_EX(op_array, opline->opN, ssa->rt_constants); \
return (Z_TYPE_P(zv) == IS_LONG || Z_TYPE_P(zv) == IS_TRUE || Z_TYPE_P(zv) == IS_FALSE || Z_TYPE_P(zv) == IS_NULL); \
} else { \
return (opline->opN##_type != IS_UNUSED && \
ssa->ops && \
ssa->var_info && \
ssa->ops[opline - op_array->opcodes].opN##_use >= 0 && \
ssa->var_info[ssa->ops[opline - op_array->opcodes].opN##_use].has_range); \
} \
return 0; \
}
#define DEFINE_SSA_OP_MIN_RANGE(opN) \
static zend_always_inline long _ssa_##opN##_min_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline) \
{ \
if (opline->opN##_type == IS_CONST) { \
zval *zv = CRT_CONSTANT_EX(op_array, opline->opN, ssa->rt_constants); \
if (Z_TYPE_P(zv) == IS_LONG) { \
return Z_LVAL_P(zv); \
} else if (Z_TYPE_P(zv) == IS_TRUE) { \
return 1; \
} else if (Z_TYPE_P(zv) == IS_FALSE) { \
return 0; \
} else if (Z_TYPE_P(zv) == IS_NULL) { \
return 0; \
} \
} else if (opline->opN##_type != IS_UNUSED && \
ssa->ops && \
ssa->var_info && \
ssa->ops[opline - op_array->opcodes].opN##_use >= 0 && \
ssa->var_info[ssa->ops[opline - op_array->opcodes].opN##_use].has_range) { \
return ssa->var_info[ssa->ops[opline - op_array->opcodes].opN##_use].range.min; \
} \
return LONG_MIN; \
}
#define DEFINE_SSA_OP_MAX_RANGE(opN) \
static zend_always_inline long _ssa_##opN##_max_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline) \
{ \
if (opline->opN##_type == IS_CONST) { \
zval *zv = CRT_CONSTANT_EX(op_array, opline->opN, ssa->rt_constants); \
if (Z_TYPE_P(zv) == IS_LONG) { \
return Z_LVAL_P(zv); \
} else if (Z_TYPE_P(zv) == IS_TRUE) { \
return 1; \
} else if (Z_TYPE_P(zv) == IS_FALSE) { \
return 0; \
} else if (Z_TYPE_P(zv) == IS_NULL) { \
return 0; \
} \
} else if (opline->opN##_type != IS_UNUSED && \
ssa->ops && \
ssa->var_info && \
ssa->ops[opline - op_array->opcodes].opN##_use >= 0 && \
ssa->var_info[ssa->ops[opline - op_array->opcodes].opN##_use].has_range) { \
return ssa->var_info[ssa->ops[opline - op_array->opcodes].opN##_use].range.max; \
} \
return LONG_MAX; \
}
#define DEFINE_SSA_OP_RANGE_UNDERFLOW(opN) \
static zend_always_inline char _ssa_##opN##_range_underflow(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline) \
{ \
if (opline->opN##_type == IS_CONST) { \
zval *zv = CRT_CONSTANT_EX(op_array, opline->opN, ssa->rt_constants); \
if (Z_TYPE_P(zv) == IS_LONG || Z_TYPE_P(zv) == IS_TRUE || Z_TYPE_P(zv) == IS_FALSE || Z_TYPE_P(zv) == IS_NULL) { \
return 0; \
} \
} else if (opline->opN##_type != IS_UNUSED && \
ssa->ops && \
ssa->var_info && \
ssa->ops[opline - op_array->opcodes].opN##_use >= 0 && \
ssa->var_info[ssa->ops[opline - op_array->opcodes].opN##_use].has_range) { \
return ssa->var_info[ssa->ops[opline - op_array->opcodes].opN##_use].range.underflow; \
} \
return 1; \
}
#define DEFINE_SSA_OP_RANGE_OVERFLOW(opN) \
static zend_always_inline char _ssa_##opN##_range_overflow(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline) \
{ \
if (opline->opN##_type == IS_CONST) { \
zval *zv = CRT_CONSTANT_EX(op_array, opline->opN, ssa->rt_constants); \
if (Z_TYPE_P(zv) == IS_LONG || Z_TYPE_P(zv) == IS_TRUE || Z_TYPE_P(zv) == IS_FALSE || Z_TYPE_P(zv) == IS_NULL) { \
return 0; \
} \
} else if (opline->opN##_type != IS_UNUSED && \
ssa->ops && \
ssa->var_info && \
ssa->ops[opline - op_array->opcodes].opN##_use >= 0 && \
ssa->var_info[ssa->ops[opline - op_array->opcodes].opN##_use].has_range) { \
return ssa->var_info[ssa->ops[opline - op_array->opcodes].opN##_use].range.overflow; \
} \
return 1; \
}
DEFINE_SSA_OP_HAS_RANGE(op1)
DEFINE_SSA_OP_MIN_RANGE(op1)
DEFINE_SSA_OP_MAX_RANGE(op1)
DEFINE_SSA_OP_RANGE_UNDERFLOW(op1)
DEFINE_SSA_OP_RANGE_OVERFLOW(op1)
DEFINE_SSA_OP_HAS_RANGE(op2)
DEFINE_SSA_OP_MIN_RANGE(op2)
DEFINE_SSA_OP_MAX_RANGE(op2)
DEFINE_SSA_OP_RANGE_UNDERFLOW(op2)
DEFINE_SSA_OP_RANGE_OVERFLOW(op2)
#define OP1_HAS_RANGE() (_ssa_op1_has_range (op_array, ssa, opline))
#define OP1_MIN_RANGE() (_ssa_op1_min_range (op_array, ssa, opline))
#define OP1_MAX_RANGE() (_ssa_op1_max_range (op_array, ssa, opline))
#define OP1_RANGE_UNDERFLOW() (_ssa_op1_range_underflow (op_array, ssa, opline))
#define OP1_RANGE_OVERFLOW() (_ssa_op1_range_overflow (op_array, ssa, opline))
#define OP2_HAS_RANGE() (_ssa_op2_has_range (op_array, ssa, opline))
#define OP2_MIN_RANGE() (_ssa_op2_min_range (op_array, ssa, opline))
#define OP2_MAX_RANGE() (_ssa_op2_max_range (op_array, ssa, opline))
#define OP2_RANGE_UNDERFLOW() (_ssa_op2_range_underflow (op_array, ssa, opline))
#define OP2_RANGE_OVERFLOW() (_ssa_op2_range_overflow (op_array, ssa, opline))
static zend_always_inline uint32_t _const_op_type(const zval *zv) {
if (Z_TYPE_P(zv) == IS_CONSTANT) {
return MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
} else if (Z_TYPE_P(zv) == IS_CONSTANT_AST) {
return MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY;
} else if (Z_TYPE_P(zv) == IS_ARRAY) {
HashTable *ht = Z_ARRVAL_P(zv);
uint32_t tmp = MAY_BE_ARRAY | MAY_BE_DEF | MAY_BE_RC1;
zend_string *str;
zval *val;
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, str, val) {
if (str) {
tmp |= MAY_BE_ARRAY_KEY_STRING;
} else {
tmp |= MAY_BE_ARRAY_KEY_LONG;
}
tmp |= 1 << (Z_TYPE_P(val) + MAY_BE_ARRAY_SHIFT);
} ZEND_HASH_FOREACH_END();
return tmp;
} else {
return (1 << Z_TYPE_P(zv)) | MAY_BE_DEF | MAY_BE_RC1;
}
}
static zend_always_inline uint32_t get_ssa_var_info(const zend_ssa *ssa, int ssa_var_num)
{
if (ssa->var_info && ssa_var_num >= 0) {
return ssa->var_info[ssa_var_num].type;
} else {
return MAY_BE_DEF | MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_ERROR;
}
}
#define DEFINE_SSA_OP_INFO(opN) \
static zend_always_inline uint32_t _ssa_##opN##_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline) \
{ \
if (opline->opN##_type == IS_CONST) { \
return _const_op_type(CRT_CONSTANT_EX(op_array, opline->opN, ssa->rt_constants)); \
} else { \
return get_ssa_var_info(ssa, ssa->ops ? ssa->ops[opline - op_array->opcodes].opN##_use : -1); \
} \
}
#define DEFINE_SSA_OP_DEF_INFO(opN) \
static zend_always_inline uint32_t _ssa_##opN##_def_info(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline) \
{ \
return get_ssa_var_info(ssa, ssa->ops ? ssa->ops[opline - op_array->opcodes].opN##_def : -1); \
}
DEFINE_SSA_OP_INFO(op1)
DEFINE_SSA_OP_INFO(op2)
DEFINE_SSA_OP_INFO(result)
DEFINE_SSA_OP_DEF_INFO(op1)
DEFINE_SSA_OP_DEF_INFO(op2)
DEFINE_SSA_OP_DEF_INFO(result)
#define OP1_INFO() (_ssa_op1_info(op_array, ssa, opline))
#define OP2_INFO() (_ssa_op2_info(op_array, ssa, opline))
#define OP1_DATA_INFO() (_ssa_op1_info(op_array, ssa, (opline+1)))
#define OP2_DATA_INFO() (_ssa_op2_info(op_array, ssa, (opline+1)))
#define RES_USE_INFO() (_ssa_result_info(op_array, ssa, opline))
#define OP1_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, opline))
#define OP2_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, opline))
#define OP1_DATA_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, (opline+1)))
#define OP2_DATA_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, (opline+1)))
#define RES_INFO() (_ssa_result_def_info(op_array, ssa, opline))
BEGIN_EXTERN_C()
int zend_ssa_find_false_dependencies(const zend_op_array *op_array, zend_ssa *ssa);
int zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa);
int zend_ssa_inference(zend_arena **raena, const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa);
uint32_t zend_array_element_type(uint32_t t1, int write, int insert);
int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int var, int widening, int narrowing, zend_ssa_range *tmp);
void zend_inference_init_range(const zend_op_array *op_array, zend_ssa *ssa, int var, zend_bool underflow, long min, long max, zend_bool overflow);
int zend_inference_narrowing_meet(zend_ssa_var_info *var_info, zend_ssa_range *r);
int zend_inference_widening_meet(zend_ssa_var_info *var_info, zend_ssa_range *r);
void zend_inference_check_recursive_dependencies(zend_op_array *op_array);
int zend_infer_types_ex(const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_bitset worklist);
void zend_func_return_info(const zend_op_array *op_array,
int recursive,
int widening,
zend_ssa_var_info *ret);
END_EXTERN_C()
#endif /* ZEND_INFERENCE_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
+91 -10
View File
@@ -26,6 +26,9 @@
#include "zend_constants.h"
#include "zend_execute.h"
#include "zend_vm.h"
#include "zend_cfg.h"
#include "zend_func_info.h"
#include "zend_dump.h"
static void zend_optimizer_zval_dtor_wrapper(zval *zvalue)
{
@@ -132,6 +135,10 @@ static inline void drop_leading_backslash(zval *val) {
}
}
static inline void alloc_cache_slots_op1(zend_op_array *op_array, zend_op *opline, uint32_t num) {
Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size;
op_array->cache_size += num * sizeof(void *);
}
static inline void alloc_cache_slots_op2(zend_op_array *op_array, zend_op *opline, uint32_t num) {
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
op_array->cache_size += num * sizeof(void *);
@@ -160,7 +167,7 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
case ZEND_FREE:
MAKE_NOP(opline);
zval_dtor(val);
break;
return 1;
case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_CATCH:
case ZEND_FETCH_CONSTANT:
@@ -168,27 +175,40 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
case ZEND_DEFINED:
case ZEND_NEW:
REQUIRES_STRING(val);
ZEND_OP1_TYPE(opline) = IS_CONST;
drop_leading_backslash(val);
opline->op1.constant = zend_optimizer_add_literal(op_array, val);
zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline)));
Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size;
op_array->cache_size += sizeof(void*);
alloc_cache_slots_op1(op_array, opline, 1);
zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
break;
case ZEND_FETCH_STATIC_PROP_R:
case ZEND_FETCH_STATIC_PROP_W:
case ZEND_FETCH_STATIC_PROP_RW:
case ZEND_FETCH_STATIC_PROP_IS:
case ZEND_FETCH_STATIC_PROP_UNSET:
case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
TO_STRING_NOWARN(val);
opline->op1.constant = zend_optimizer_add_literal(op_array, val);
alloc_cache_slots_op1(op_array, opline, 2);
break;
case ZEND_CONCAT:
case ZEND_FAST_CONCAT:
case ZEND_FETCH_R:
case ZEND_FETCH_W:
case ZEND_FETCH_RW:
case ZEND_FETCH_IS:
case ZEND_FETCH_UNSET:
case ZEND_FETCH_FUNC_ARG:
TO_STRING_NOWARN(val);
/* break missing intentionally */
default:
ZEND_OP1_TYPE(opline) = IS_CONST;
opline->op1.constant = zend_optimizer_add_literal(op_array, val);
if (Z_TYPE_P(val) == IS_STRING) {
zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline)));
}
break;
}
ZEND_OP1_TYPE(opline) = IS_CONST;
if (Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING) {
zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline)));
}
return 1;
}
@@ -529,6 +549,10 @@ static void zend_optimize(zend_op_array *op_array,
return;
}
if (ctx->debug_level & ZEND_DUMP_BEFORE_OPTIMIZER) {
zend_dump_op_array(op_array, 0, "before optimizer", NULL);
}
/* pass 1
* - substitute persistent constants (true, false, null, etc)
* - perform compile-time evaluation of constant binary and unary operations
@@ -537,6 +561,9 @@ static void zend_optimize(zend_op_array *op_array,
*/
if (ZEND_OPTIMIZER_PASS_1 & ctx->optimization_level) {
zend_optimizer_pass1(op_array, ctx);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_1) {
zend_dump_op_array(op_array, 0, "after pass 1", NULL);
}
}
/* pass 2:
@@ -547,6 +574,9 @@ static void zend_optimize(zend_op_array *op_array,
*/
if (ZEND_OPTIMIZER_PASS_2 & ctx->optimization_level) {
zend_optimizer_pass2(op_array);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_2) {
zend_dump_op_array(op_array, 0, "after pass 2", NULL);
}
}
/* pass 3:
@@ -556,6 +586,9 @@ static void zend_optimize(zend_op_array *op_array,
*/
if (ZEND_OPTIMIZER_PASS_3 & ctx->optimization_level) {
zend_optimizer_pass3(op_array);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_3) {
zend_dump_op_array(op_array, 0, "after pass 1", NULL);
}
}
/* pass 4:
@@ -563,6 +596,9 @@ static void zend_optimize(zend_op_array *op_array,
*/
if (ZEND_OPTIMIZER_PASS_4 & ctx->optimization_level) {
optimize_func_calls(op_array, ctx);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_4) {
zend_dump_op_array(op_array, 0, "after pass 1", NULL);
}
}
/* pass 5:
@@ -570,6 +606,19 @@ static void zend_optimize(zend_op_array *op_array,
*/
if (ZEND_OPTIMIZER_PASS_5 & ctx->optimization_level) {
optimize_cfg(op_array, ctx);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_5) {
zend_dump_op_array(op_array, 0, "after pass 5", NULL);
}
}
/* pass 6:
* - DFA optimization
*/
if (ZEND_OPTIMIZER_PASS_6 & ctx->optimization_level) {
optimize_dfa(op_array, ctx);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_6) {
zend_dump_op_array(op_array, 0, "after pass 6", NULL);
}
}
/* pass 9:
@@ -577,6 +626,9 @@ static void zend_optimize(zend_op_array *op_array,
*/
if (ZEND_OPTIMIZER_PASS_9 & ctx->optimization_level) {
optimize_temporary_variables(op_array, ctx);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_9) {
zend_dump_op_array(op_array, 0, "after pass 9", NULL);
}
}
/* pass 10:
@@ -584,6 +636,9 @@ static void zend_optimize(zend_op_array *op_array,
*/
if (((ZEND_OPTIMIZER_PASS_10|ZEND_OPTIMIZER_PASS_5) & ctx->optimization_level) == ZEND_OPTIMIZER_PASS_10) {
zend_optimizer_nop_removal(op_array);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_10) {
zend_dump_op_array(op_array, 0, "after pass 10", NULL);
}
}
/* pass 11:
@@ -591,6 +646,13 @@ static void zend_optimize(zend_op_array *op_array,
*/
if (ZEND_OPTIMIZER_PASS_11 & ctx->optimization_level) {
zend_optimizer_compact_literals(op_array, ctx);
if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_11) {
zend_dump_op_array(op_array, 0, "after pass 11", NULL);
}
}
if (ctx->debug_level & ZEND_DUMP_AFTER_OPTIMIZER) {
zend_dump_op_array(op_array, 0, "after optimizer", NULL);
}
}
@@ -650,7 +712,7 @@ static void zend_adjust_fcall_stack_size(zend_op_array *op_array, zend_optimizer
}
}
int zend_optimize_script(zend_script *script, zend_long optimization_level)
int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level)
{
uint idx, j;
Bucket *p, *q;
@@ -662,6 +724,7 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level)
ctx.script = script;
ctx.constants = NULL;
ctx.optimization_level = optimization_level;
ctx.debug_level = debug_level;
zend_optimize_op_array(&script->main_op_array, &ctx);
@@ -732,3 +795,21 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level)
return 1;
}
int zend_optimizer_startup(void)
{
return zend_func_info_startup();
}
int zend_optimizer_shutdown(void)
{
return zend_func_info_shutdown();
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
+36 -2
View File
@@ -30,7 +30,7 @@
#define ZEND_OPTIMIZER_PASS_3 (1<<2) /* ++, +=, series of jumps */
#define ZEND_OPTIMIZER_PASS_4 (1<<3) /* INIT_FCALL_BY_NAME -> DO_FCALL */
#define ZEND_OPTIMIZER_PASS_5 (1<<4) /* CFG based optimization */
#define ZEND_OPTIMIZER_PASS_6 (1<<5)
#define ZEND_OPTIMIZER_PASS_6 (1<<5) /* DFA based optimization */
#define ZEND_OPTIMIZER_PASS_7 (1<<6)
#define ZEND_OPTIMIZER_PASS_8 (1<<7)
#define ZEND_OPTIMIZER_PASS_9 (1<<8) /* TMP VAR usage */
@@ -44,6 +44,38 @@
#define DEFAULT_OPTIMIZATION_LEVEL "0xFFFFFFFF"
#define ZEND_DUMP_AFTER_PASS_1 ZEND_OPTIMIZER_PASS_1
#define ZEND_DUMP_AFTER_PASS_2 ZEND_OPTIMIZER_PASS_2
#define ZEND_DUMP_AFTER_PASS_3 ZEND_OPTIMIZER_PASS_3
#define ZEND_DUMP_AFTER_PASS_4 ZEND_OPTIMIZER_PASS_4
#define ZEND_DUMP_AFTER_PASS_5 ZEND_OPTIMIZER_PASS_5
#define ZEND_DUMP_AFTER_PASS_6 ZEND_OPTIMIZER_PASS_6
#define ZEND_DUMP_AFTER_PASS_7 ZEND_OPTIMIZER_PASS_7
#define ZEND_DUMP_AFTER_PASS_8 ZEND_OPTIMIZER_PASS_8
#define ZEND_DUMP_AFTER_PASS_9 ZEND_OPTIMIZER_PASS_9
#define ZEND_DUMP_AFTER_PASS_10 ZEND_OPTIMIZER_PASS_10
#define ZEND_DUMP_AFTER_PASS_11 ZEND_OPTIMIZER_PASS_11
#define ZEND_DUMP_AFTER_PASS_12 ZEND_OPTIMIZER_PASS_12
#define ZEND_DUMP_AFTER_PASS_13 ZEND_OPTIMIZER_PASS_13
#define ZEND_DUMP_AFTER_PASS_14 ZEND_OPTIMIZER_PASS_14
#define ZEND_DUMP_BEFORE_OPTIMIZER (1<<16)
#define ZEND_DUMP_AFTER_OPTIMIZER (1<<17)
#define ZEND_DUMP_BEFORE_BLOCK_PASS (1<<18)
#define ZEND_DUMP_AFTER_BLOCK_PASS (1<<19)
#define ZEND_DUMP_BLOCK_PASS_VARS (1<<20)
#define ZEND_DUMP_BEFORE_DFA_PASS (1<<21)
#define ZEND_DUMP_AFTER_DFA_PASS (1<<22)
#define ZEND_DUMP_DFA_CFG (1<<23)
#define ZEND_DUMP_DFA_DOMINATORS (1<<24)
#define ZEND_DUMP_DFA_LIVENESS (1<<25)
#define ZEND_DUMP_DFA_PHI (1<<26)
#define ZEND_DUMP_DFA_SSA (1<<27)
#define ZEND_DUMP_DFA_SSA_VARS (1<<28)
typedef struct _zend_script {
zend_string *filename;
zend_op_array main_op_array;
@@ -51,6 +83,8 @@ typedef struct _zend_script {
HashTable class_table;
} zend_script;
int zend_optimize_script(zend_script *script, zend_long optimization_level);
int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level);
int zend_optimizer_startup(void);
int zend_optimizer_shutdown(void);
#endif
@@ -49,6 +49,7 @@ typedef struct _zend_optimizer_ctx {
zend_script *script;
HashTable *constants;
zend_long optimization_level;
zend_long debug_level;
} zend_optimizer_ctx;
#define LITERAL_LONG(op, val) do { \
@@ -96,6 +97,7 @@ void zend_optimizer_pass2(zend_op_array *op_array);
void zend_optimizer_pass3(zend_op_array *op_array);
void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx);
void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx);
void optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx);
void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *ctx);
void zend_optimizer_nop_removal(zend_op_array *op_array);
void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx);
File diff suppressed because it is too large Load Diff
+156
View File
@@ -0,0 +1,156 @@
/*
+----------------------------------------------------------------------+
| Zend Engine, SSA - Static Single Assignment Form |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2015 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_SSA_H
#define ZEND_SSA_H
#include "zend_cfg.h"
typedef struct _zend_ssa_range {
zend_long min;
zend_long max;
zend_bool underflow;
zend_bool overflow;
} zend_ssa_range;
typedef enum _zend_ssa_negative_lat {
NEG_NONE = 0,
NEG_INIT = 1,
NEG_INVARIANT = 2,
NEG_USE_LT = 3,
NEG_USE_GT = 4,
NEG_UNKNOWN = 5
} zend_ssa_negative_lat;
/* Special kind of SSA Phi function used in eSSA */
typedef struct _zend_ssa_pi_range {
zend_ssa_range range; /* simple range constraint */
int min_var;
int max_var;
int min_ssa_var; /* ((min_var>0) ? MIN(ssa_var) : 0) + range.min */
int max_ssa_var; /* ((man_var>0) ? MAX(ssa_var) : 0) + range.man */
zend_ssa_negative_lat negative;
} zend_ssa_pi_range;
/* SSA Phi - ssa_var = Phi(source0, source1, ...sourceN) */
typedef struct _zend_ssa_phi zend_ssa_phi;
struct _zend_ssa_phi {
zend_ssa_phi *next; /* next Phi in the same BB */
int pi; /* if >= 0 this is actually a e-SSA Pi */
zend_ssa_pi_range constraint; /* e-SSA Pi constraint */
int var; /* Original CV, VAR or TMP variable index */
int ssa_var; /* SSA variable index */
int block; /* current BB index */
int visited; /* flag to avoid recursive processing */
zend_ssa_phi **use_chains;
zend_ssa_phi *sym_use_chain;
int *sources; /* Array of SSA IDs that produce this var.
As many as this block has
predecessors. */
};
typedef struct _zend_ssa_block {
zend_ssa_phi *phis;
} zend_ssa_block;
typedef struct _zend_ssa_op {
int op1_use;
int op2_use;
int result_use;
int op1_def;
int op2_def;
int result_def;
int op1_use_chain;
int op2_use_chain;
int res_use_chain;
} zend_ssa_op;
typedef struct _zend_ssa_var {
int var; /* original var number; op.var for CVs and following numbers for VARs and TMP_VARs */
int scc; /* strongly connected component */
int definition; /* opcode that defines this value */
zend_ssa_phi *definition_phi; /* phi that defines this value */
int use_chain; /* uses of this value, linked through opN_use_chain */
zend_ssa_phi *phi_use_chain; /* uses of this value in Phi, linked through use_chain */
zend_ssa_phi *sym_use_chain; /* uses of this value in Pi constaints */
unsigned int no_val : 1; /* value doesn't mater (used as op1 in ZEND_ASSIGN) */
unsigned int scc_entry : 1;
} zend_ssa_var;
typedef struct _zend_ssa_var_info {
uint32_t type; /* inferred type (see zend_inference.h) */
zend_ssa_range range;
zend_class_entry *ce;
unsigned int has_range : 1;
unsigned int is_instanceof : 1; /* 0 - class == "ce", 1 - may be child of "ce" */
unsigned int recursive : 1;
unsigned int use_as_double : 1;
} zend_ssa_var_info;
typedef struct _zend_ssa {
zend_cfg cfg; /* control flow graph */
int rt_constants; /* run-time or compile-time */
int vars_count; /* number of SSA variables */
zend_ssa_block *blocks; /* array of SSA blocks */
zend_ssa_op *ops; /* array of SSA instructions */
zend_ssa_var *vars; /* use/def chain of SSA variables */
int sccs; /* number of SCCs */
zend_ssa_var_info *var_info;
} zend_ssa;
BEGIN_EXTERN_C()
int zend_build_ssa(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, uint32_t *func_flags);
int zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_array, zend_ssa *ssa);
int zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var);
END_EXTERN_C()
static zend_always_inline int zend_ssa_next_use(zend_ssa_op *ssa_op, int var, int use)
{
ssa_op += use;
if (ssa_op->result_use == var) {
return ssa_op->res_use_chain;
}
return (ssa_op->op1_use == var) ? ssa_op->op1_use_chain : ssa_op->op2_use_chain;
}
static zend_always_inline zend_ssa_phi* zend_ssa_next_use_phi(zend_ssa *ssa, int var, zend_ssa_phi *p)
{
if (p->pi >= 0) {
return p->use_chains[0];
} else {
int j;
for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
if (p->sources[j] == var) {
return p->use_chains[j];
}
}
}
return NULL;
}
#endif /* ZEND_SSA_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
+137
View File
@@ -0,0 +1,137 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2015 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andy Wingo <wingo@igalia.com> |
+----------------------------------------------------------------------+
*/
/* $Id:$ */
#ifndef _ZEND_WORKLIST_H_
#define _ZEND_WORKLIST_H_
#include "zend_arena.h"
#include "zend_bitset.h"
typedef struct _zend_worklist_stack {
int *buf;
int len;
int capacity;
} zend_worklist_stack;
#define ZEND_WORKLIST_STACK_ALLOCA(s, _len, use_heap) do { \
(s)->buf = (int*)do_alloca(sizeof(int) * _len, use_heap); \
(s)->len = 0; \
(s)->capacity = _len; \
} while (0)
#define ZEND_WORKLIST_STACK_FREE_ALLOCA(s, use_heap) \
free_alloca((s)->buf, use_heap)
static inline int zend_worklist_stack_prepare(zend_arena **arena, zend_worklist_stack *stack, int len)
{
ZEND_ASSERT(len >= 0);
stack->buf = (int*)zend_arena_calloc(arena, sizeof(*stack->buf), len);
if (!stack->buf) {
return FAILURE;
}
stack->len = 0;
stack->capacity = len;
return SUCCESS;
}
static inline void zend_worklist_stack_push(zend_worklist_stack *stack, int i)
{
ZEND_ASSERT(stack->len < stack->capacity);
stack->buf[stack->len++] = i;
}
static inline int zend_worklist_stack_peek(zend_worklist_stack *stack)
{
ZEND_ASSERT(stack->len);
return stack->buf[stack->len - 1];
}
static inline int zend_worklist_stack_pop(zend_worklist_stack *stack)
{
ZEND_ASSERT(stack->len);
return stack->buf[--stack->len];
}
typedef struct _zend_worklist {
zend_bitset visited;
zend_worklist_stack stack;
} zend_worklist;
#define ZEND_WORKLIST_ALLOCA(w, _len, use_heap) do { \
(w)->stack.buf = (int*)do_alloca(sizeof(int) * _len + sizeof(zend_ulong) * zend_bitset_len(_len), use_heap); \
(w)->stack.len = 0; \
(w)->stack.capacity = _len; \
(w)->visited = (zend_bitset)((w)->stack.buf + _len); \
memset((w)->visited, 0, sizeof(zend_ulong) * zend_bitset_len(_len)); \
} while (0)
#define ZEND_WORKLIST_FREE_ALLOCA(w, use_heap) \
free_alloca((w)->stack.buf, use_heap)
static inline int zend_worklist_prepare(zend_arena **arena, zend_worklist *worklist, int len)
{
ZEND_ASSERT(len >= 0);
worklist->visited = (zend_bitset)zend_arena_calloc(arena, sizeof(zend_ulong), zend_bitset_len(len));
if (!worklist->visited) {
return FAILURE;
}
return zend_worklist_stack_prepare(arena, &worklist->stack, len);
}
static inline int zend_worklist_len(zend_worklist *worklist)
{
return worklist->stack.len;
}
static inline int zend_worklist_push(zend_worklist *worklist, int i)
{
ZEND_ASSERT(i >= 0 && i < worklist->stack.capacity);
if (zend_bitset_in(worklist->visited, i)) {
return 0;
}
zend_bitset_incl(worklist->visited, i);
zend_worklist_stack_push(&worklist->stack, i);
return 1;
}
static inline int zend_worklist_peek(zend_worklist *worklist)
{
return zend_worklist_stack_peek(&worklist->stack);
}
static inline int zend_worklist_pop(zend_worklist *worklist)
{
/* Does not clear visited flag */
return zend_worklist_stack_pop(&worklist->stack);
}
#endif /* _ZEND_WORKLIST_H_ */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/
+3 -2
View File
@@ -1157,7 +1157,7 @@ static zend_persistent_script *cache_script_in_file_cache(zend_persistent_script
return new_persistent_script;
}
if (!zend_optimize_script(&new_persistent_script->script, ZCG(accel_directives).optimization_level)) {
if (!zend_optimize_script(&new_persistent_script->script, ZCG(accel_directives).optimization_level, ZCG(accel_directives).opt_debug_level)) {
return new_persistent_script;
}
@@ -1215,7 +1215,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
return new_persistent_script;
}
if (!zend_optimize_script(&new_persistent_script->script, ZCG(accel_directives).optimization_level)) {
if (!zend_optimize_script(&new_persistent_script->script, ZCG(accel_directives).optimization_level, ZCG(accel_directives).opt_debug_level)) {
return new_persistent_script;
}
@@ -2348,6 +2348,7 @@ static inline int accel_find_sapi(void)
"apache2filter",
"apache2handler",
"litespeed",
"uwsgi",
NULL
};
const char **sapi_name;
+1
View File
@@ -191,6 +191,7 @@ typedef struct _zend_accel_directives {
zend_long log_verbosity_level;
zend_long optimization_level;
zend_long opt_debug_level;
zend_long max_file_size;
zend_long interned_strings_buffer;
char *restrict_api;
+6
View File
@@ -404,6 +404,12 @@ fi
Optimizer/nop_removal.c \
Optimizer/compact_literals.c \
Optimizer/zend_cfg.c \
Optimizer/zend_dfg.c \
Optimizer/dfa_pass.c \
Optimizer/zend_ssa.c \
Optimizer/zend_inference.c \
Optimizer/zend_func_info.c \
Optimizer/zend_call_graph.c \
Optimizer/zend_dump.c,
shared,,-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1,,yes)
+1 -1
View File
@@ -23,7 +23,7 @@ if (PHP_OPCACHE != "no") {
zend_shared_alloc.c \
shared_alloc_win32.c", true, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
ADD_SOURCES(configure_module_dirname + "/Optimizer", "zend_optimizer.c pass1_5.c pass2.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dump.c", "opcache", "OptimizerObj");
ADD_SOURCES(configure_module_dirname + "/Optimizer", "zend_optimizer.c pass1_5.c pass2.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c", "opcache", "OptimizerObj");
ADD_FLAG('CFLAGS_OPCACHE', "/I " + configure_module_dirname);
+24
View File
@@ -0,0 +1,24 @@
--TEST--
Bug #71127 (Define in auto_prepend_file is overwrite)
--INI--
opcache.enable=1
opcache.enable_cli=1
--SKIPIF--
<?php if (!extension_loaded('Zend OPcache')) die("skip"); ?>
--FILE--
<?php
$file = __DIR__ . "/bug71127.inc";
file_put_contents($file, "<?php define('FOO', 'bad'); echo FOO;?>");
define("FOO", "okey");
include($file);
?>
--CLEAN--
<?php
@unlink(__DIR__ . "/bug71127.inc");
?>
--EXPECTF--
Notice: Constant FOO already defined in %sbug71127.inc on line %d
okey
+1
View File
@@ -294,6 +294,7 @@ ZEND_INI_BEGIN()
STD_PHP_INI_ENTRY("opcache.fast_shutdown" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.fast_shutdown, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.optimization_level" , DEFAULT_OPTIMIZATION_LEVEL , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.optimization_level, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.opt_debug_level" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.opt_debug_level, zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.enable_file_override" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_override_enabled, zend_accel_globals, accel_globals)
STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals)
STD_PHP_INI_ENTRY("opcache.error_log" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.error_log, zend_accel_globals, accel_globals)
+10 -3
View File
@@ -1283,9 +1283,16 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
}
/* verify header */
if (memcmp(info.magic, "OPCACHE", 8) != 0 ||
memcmp(info.system_id, ZCG(system_id), 32) != 0) {
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s'\n", filename);
if (memcmp(info.magic, "OPCACHE", 8) != 0) {
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (wrong header)\n", filename);
zend_file_cache_flock(fd, LOCK_UN);
close(fd);
unlink(filename);
efree(filename);
return NULL;
}
if (memcmp(info.system_id, ZCG(system_id), 32) != 0) {
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (wrong \"system_id\")\n", filename);
zend_file_cache_flock(fd, LOCK_UN);
close(fd);
unlink(filename);
+78 -46
View File
@@ -208,6 +208,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_notice, 0, 0, 1)
ZEND_ARG_INFO(0, connection)
ZEND_ARG_INFO(0, all_notices)
ZEND_END_ARG_INFO()
#ifdef HAVE_PQFTABLE
@@ -276,6 +277,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, numeric_index)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all_columns, 0, 0, 1)
@@ -961,29 +963,24 @@ static void _close_pgsql_plink(zend_resource *rsrc)
*/
static void _php_pgsql_notice_handler(void *resource_id, const char *message)
{
php_pgsql_notice *notice;
zval *notices;
zval tmp;
char *trimed_message;
size_t trimed_message_len;
if (! PGG(ignore_notices)) {
notice = (php_pgsql_notice *)emalloc(sizeof(php_pgsql_notice));
notice->message = _php_pgsql_trim_message(message, &notice->len);
if (PGG(log_notices)) {
php_error_docref(NULL, E_NOTICE, "%s", notice->message);
notices = zend_hash_index_find(&PGG(notices), (zend_ulong)resource_id);
if (!notices) {
array_init(&tmp);
notices = &tmp;
zend_hash_index_update(&PGG(notices), (zend_ulong)resource_id, notices);
}
zend_hash_index_update_ptr(&PGG(notices), (zend_ulong)resource_id, notice);
}
}
/* }}} */
#define PHP_PGSQL_NOTICE_PTR_DTOR _php_pgsql_notice_ptr_dtor
/* {{{ _php_pgsql_notice_dtor
*/
static void _php_pgsql_notice_ptr_dtor(zval *el)
{
php_pgsql_notice *notice = (php_pgsql_notice *)Z_PTR_P(el);
if (notice) {
efree(notice->message);
efree(notice);
trimed_message = _php_pgsql_trim_message(message, &trimed_message_len);
if (PGG(log_notices)) {
php_error_docref(NULL, E_NOTICE, "%s", trimed_message);
}
add_next_index_stringl(notices, trimed_message, trimed_message_len);
efree(trimed_message);
}
}
/* }}} */
@@ -1096,7 +1093,7 @@ static PHP_GINIT_FUNCTION(pgsql)
#endif
memset(pgsql_globals, 0, sizeof(zend_pgsql_globals));
/* Initilize notice message hash at MINIT only */
zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, PHP_PGSQL_NOTICE_PTR_DTOR, 1, 0);
zend_hash_init_ex(&pgsql_globals->notices, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
}
/* }}} */
@@ -1199,6 +1196,7 @@ PHP_MINIT_FUNCTION(pgsql)
REGISTER_LONG_CONSTANT("PGSQL_DML_EXEC", PGSQL_DML_EXEC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PGSQL_DML_ASYNC", PGSQL_DML_ASYNC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PGSQL_DML_STRING", PGSQL_DML_STRING, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PGSQL_FETCH_NUM", PGSQL_FETCH_NUM, CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
/* }}} */
@@ -2306,15 +2304,16 @@ PHP_FUNCTION(pg_affected_rows)
/* }}} */
#endif
/* {{{ proto string pg_last_notice(resource connection)
/* {{{ proto mixed pg_last_notice(resource connection [, bool all_notices])
Returns the last notice set by the backend */
PHP_FUNCTION(pg_last_notice)
{
zval *pgsql_link = NULL;
zval *notice, *notices;
PGconn *pg_link;
php_pgsql_notice *notice;
zend_bool all_notices = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pgsql_link) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &pgsql_link, &all_notices) == FAILURE) {
return;
}
@@ -2323,10 +2322,26 @@ PHP_FUNCTION(pg_last_notice)
RETURN_FALSE;
}
if ((notice = zend_hash_index_find_ptr(&PGG(notices), (zend_ulong)Z_RES_HANDLE_P(pgsql_link))) == NULL) {
RETURN_FALSE;
/* PHP 7.0 and earlier returns FALSE for empty notice.
PHP 7.1> returns empty array or string */
notices = zend_hash_index_find(&PGG(notices), (zend_ulong)Z_RES_HANDLE_P(pgsql_link));
if (all_notices) {
if (notices) {
RETURN_ZVAL(notices, 1, 0);
} else {
array_init(return_value);
}
} else {
if (notices) {
zend_hash_internal_pointer_end(Z_ARRVAL_P(notices));
if ((notice = zend_hash_get_current_data(Z_ARRVAL_P(notices))) == NULL) {
RETURN_EMPTY_STRING();
}
RETURN_ZVAL(notice, 1, 0);
} else {
RETURN_EMPTY_STRING();
}
}
RETURN_STRINGL(notice->message, notice->len);
}
/* }}} */
@@ -2870,15 +2885,16 @@ PHP_FUNCTION(pg_fetch_object)
}
/* }}} */
/* {{{ proto array pg_fetch_all(resource result)
/* {{{ proto array pg_fetch_all(resource result [, bool numeric_index])
Fetch all rows into array */
PHP_FUNCTION(pg_fetch_all)
{
zval *result;
zend_bool numeric_index = 0;
PGresult *pgsql_result;
pgsql_result_handle *pg_result;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &result) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &result, &numeric_index) == FAILURE) {
return;
}
@@ -2888,7 +2904,7 @@ PHP_FUNCTION(pg_fetch_all)
pgsql_result = pg_result->result;
array_init(return_value);
if (php_pgsql_result2array(pgsql_result, return_value) == FAILURE) {
if (php_pgsql_result2array(pgsql_result, return_value, numeric_index) == FAILURE) {
zval_dtor(return_value);
RETURN_FALSE;
}
@@ -7002,7 +7018,7 @@ PHP_FUNCTION(pg_delete)
/* {{{ php_pgsql_result2array
*/
PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array)
PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, zend_bool numeric_index)
{
zval row;
char *field_name;
@@ -7014,23 +7030,39 @@ PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array)
if ((pg_numrows = PQntuples(pg_result)) <= 0) {
return FAILURE;
}
for (pg_row = 0; pg_row < pg_numrows; pg_row++) {
array_init(&row);
for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) {
if (PQgetisnull(pg_result, pg_row, i)) {
field_name = PQfname(pg_result, i);
add_assoc_null(&row, field_name);
} else {
char *element = PQgetvalue(pg_result, pg_row, i);
if (element) {
const size_t element_len = strlen(element);
field_name = PQfname(pg_result, i);
add_assoc_stringl(&row, field_name, element, element_len);
if (numeric_index) {
for (pg_row = 0; pg_row < pg_numrows; pg_row++) {
array_init(&row);
for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) {
if (PQgetisnull(pg_result, pg_row, i)) {
add_next_index_null(&row);
} else {
char *element = PQgetvalue(pg_result, pg_row, i);
if (element) {
const size_t element_len = strlen(element);
add_next_index_stringl(&row, element, element_len);
}
}
}
add_index_zval(ret_array, pg_row, &row);
}
} else {
for (pg_row = 0; pg_row < pg_numrows; pg_row++) {
array_init(&row);
for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) {
field_name = PQfname(pg_result, i);
if (PQgetisnull(pg_result, pg_row, i)) {
add_assoc_null(&row, field_name);
} else {
char *element = PQgetvalue(pg_result, pg_row, i);
if (element) {
const size_t element_len = strlen(element);
add_assoc_stringl(&row, field_name, element, element_len);
}
}
}
add_index_zval(ret_array, pg_row, &row);
}
add_index_zval(ret_array, pg_row, &row);
}
return SUCCESS;
}
@@ -7076,7 +7108,7 @@ PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids
pg_result = PQexec(pg_link, ZSTR_VAL(querystr.s));
if (PQresultStatus(pg_result) == PGRES_TUPLES_OK) {
ret = php_pgsql_result2array(pg_result, ret_array);
ret = php_pgsql_result2array(pg_result, ret_array, (opt & PGSQL_FETCH_NUM));
} else {
php_error_docref(NULL, E_NOTICE, "Failed to execute '%s'", ZSTR_VAL(querystr.s));
}
+2 -2
View File
@@ -210,7 +210,7 @@ PHP_FUNCTION(pg_select);
#define PGSQL_DML_ASYNC (1<<10) /* Do async query */
#define PGSQL_DML_STRING (1<<11) /* Return query string */
#define PGSQL_DML_ESCAPE (1<<12) /* No convert, but escape only */
#define PGSQL_FETCH_NUM (1<<13) /* Fetch result with numeric index */
/* exported functions */
PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta, zend_bool extended);
@@ -219,7 +219,7 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *val
PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *values, zval *ids, zend_ulong opt , zend_string **sql);
PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids, zend_ulong opt, zend_string **sql);
PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids, zval *ret_array, zend_ulong opt, zend_string **sql );
PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array);
PHP_PGSQL_API int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, zend_bool numeric_index);
/* internal functions */
static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent);
+29 -13
View File
@@ -9,35 +9,51 @@ _skip_lc_messages();
?>
--INI--
pgsql.log_notice=1
pgsql.ignore_notice=0
--FILE--
<?php
include 'config.inc';
include 'lcmess.inc';
ini_set('pgsql.log_notice', TRUE);
ini_set('pgsql.ignore_notice', FALSE);
$db = pg_connect($conn_str);
_set_lc_messages();
$res = pg_query($db, 'SET client_min_messages TO NOTICE;');
$res = pg_query($db, 'SET client_min_messages TO NOTICE;');
var_dump($res);
// Get empty notice
var_dump(pg_last_notice($db));
var_dump(pg_last_notice($db, TRUE));
pg_query($db, "BEGIN;");
pg_query($db, "BEGIN;");
pg_query($db, "BEGIN;");
pg_query($db, "BEGIN;");
$msg = pg_last_notice($db);
if ($msg === FALSE) {
echo "Cannot find notice message in hash\n";
var_dump($msg);
}
echo $msg."\n";
echo "pg_last_notice() is Ok\n";
// Get notices
var_dump(pg_last_notice($db));
var_dump(pg_last_notice($db, TRUE));
?>
--EXPECTF--
resource(%d) of type (pgsql result)
string(0) ""
array(0) {
}
Notice: pg_query(): %s already a transaction in progress in %s on line %d
%s already a transaction in progress
pg_last_notice() is Ok
Notice: pg_query(): %s already a transaction in progress in %s on line %d
Notice: pg_query(): %s already a transaction in progress in %s on line %d
string(52) "WARNING: there is already a transaction in progress"
array(3) {
[0]=>
string(52) "WARNING: there is already a transaction in progress"
[1]=>
string(52) "WARNING: there is already a transaction in progress"
[2]=>
string(52) "WARNING: there is already a transaction in progress"
}
+8 -8
View File
@@ -188,7 +188,7 @@ PHP_MSHUTDOWN_FUNCTION(readline)
PHP_RSHUTDOWN_FUNCTION(readline)
{
zval_dtor(&_readline_completion);
zval_ptr_dtor(&_readline_completion);
ZVAL_UNDEF(&_readline_completion);
#if HAVE_RL_CALLBACK_READ_CHAR
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
@@ -505,7 +505,7 @@ static char **_readline_completion_cb(const char *text, int start, int end)
for (i = 0; i < 3; i++) {
zval_ptr_dtor(&params[i]);
}
zval_dtor(&_readline_array);
zval_ptr_dtor(&_readline_array);
return matches;
}
@@ -526,8 +526,8 @@ PHP_FUNCTION(readline_completion_function)
}
zend_string_release(name);
zval_dtor(&_readline_completion);
ZVAL_DUP(&_readline_completion, arg);
zval_ptr_dtor(&_readline_completion);
ZVAL_COPY(&_readline_completion, arg);
rl_attempted_completion_function = _readline_completion_cb;
if (rl_attempted_completion_function == NULL) {
@@ -552,7 +552,7 @@ static void php_rl_callback_handler(char *the_line)
call_user_function(CG(function_table), NULL, &_prepped_callback, &dummy, 1, params);
zval_ptr_dtor(&params[0]);
zval_dtor(&dummy);
zval_ptr_dtor(&dummy);
}
/* {{{ proto void readline_callback_handler_install(string prompt, mixed callback)
@@ -577,10 +577,10 @@ PHP_FUNCTION(readline_callback_handler_install)
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_handler_remove();
zval_dtor(&_prepped_callback);
zval_ptr_dtor(&_prepped_callback);
}
ZVAL_DUP(&_prepped_callback, callback);
ZVAL_COPY(&_prepped_callback, callback);
rl_callback_handler_install(prompt, php_rl_callback_handler);
@@ -604,7 +604,7 @@ PHP_FUNCTION(readline_callback_handler_remove)
{
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_handler_remove();
zval_dtor(&_prepped_callback);
zval_ptr_dtor(&_prepped_callback);
ZVAL_UNDEF(&_prepped_callback);
RETURN_TRUE;
}
+25 -15
View File
@@ -477,6 +477,28 @@ PHPAPI int php_session_valid_key(const char *key) /* {{{ */
}
/* }}} */
static void php_session_gc(void) /* {{{ */
{
int nrand;
/* GC must be done before reading session data. */
if ((PS(mod_data) || PS(mod_user_implemented)) && PS(gc_probability) > 0) {
int nrdels = -1;
nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg());
if (nrand < PS(gc_probability)) {
PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels);
#ifdef SESSION_DEBUG
if (nrdels != -1) {
php_error_docref(NULL, E_NOTICE, "purged %d expired session objects", nrdels);
}
#endif
}
}
} /* }}} */
static void php_session_initialize(void) /* {{{ */
{
zend_string *val = NULL;
@@ -521,6 +543,9 @@ static void php_session_initialize(void) /* {{{ */
php_session_reset_id();
PS(session_status) = php_session_active;
/* GC must be done before read */
php_session_gc();
/* Read data */
php_session_track_init();
if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, PS(gc_maxlifetime)) == FAILURE) {
@@ -1513,7 +1538,6 @@ PHPAPI void php_session_start(void) /* {{{ */
zval *ppid;
zval *data;
char *p, *value;
int nrand;
size_t lensess;
switch (PS(session_status)) {
@@ -1622,20 +1646,6 @@ PHPAPI void php_session_start(void) /* {{{ */
php_session_initialize();
php_session_cache_limiter();
if ((PS(mod_data) || PS(mod_user_implemented)) && PS(gc_probability) > 0) {
int nrdels = -1;
nrand = (int) ((float) PS(gc_divisor) * php_combined_lcg());
if (nrand < PS(gc_probability)) {
PS(mod)->s_gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels);
#ifdef SESSION_DEBUG
if (nrdels != -1) {
php_error_docref(NULL, E_NOTICE, "purged %d expired session objects", nrdels);
}
#endif
}
}
}
/* }}} */
+3 -3
View File
@@ -69,17 +69,17 @@ $_SESSION['E'] = 'F';
?>
--EXPECTF--
open: path = /tmp, name = sid
read: id = %s
gc: maxlifetime = %d
read: id = %s
write: id = %s, data = A|s:1:"B";
close
open: path = /tmp, name = sid
read: id = %s
gc: maxlifetime = %d
read: id = %s
destroy: id = %s
close
open: path = /tmp, name = sid
read: id = %s
gc: maxlifetime = %d
read: id = %s
write: id = %s, data = E|s:1:"F";
close
@@ -52,9 +52,9 @@ ob_end_flush();
*** Testing session_set_save_handler() : variation ***
Open [%s,PHPSESSID]
Read [%s,%s]
GC [0]
1 deleted
Read [%s,%s]
array(3) {
["Blah"]=>
string(12) "Hello World!"
@@ -67,20 +67,12 @@ Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;]
Close [%s,PHPSESSID]
NULL
Open [%s,PHPSESSID]
Read [%s,%s]
GC [0]
1 deleted
array(3) {
["Blah"]=>
string(12) "Hello World!"
["Foo"]=>
bool(false)
["Guff"]=>
int(1234567890)
Read [%s,%s]
array(0) {
}
Destroy [%s,%s]
Warning: unlink(%s): No such file or directory in %s on line %d
Close [%s,PHPSESSID]
bool(true)
@@ -62,9 +62,9 @@ string(0) ""
bool(true)
Open [%s,PHPSESSID]
CreateID [PHPT-%d]
Read [%s,PHPT-%d]
GC [0]
1 deleted
Read [%s,PHPT-%d]
bool(true)
string(%d) "PHPT-%d"
Write [%s,PHPT-%d,]
@@ -76,9 +76,9 @@ string(%d) "PHPT-%d"
bool(true)
Open [%s,PHPSESSID]
ValidateID [%s,PHPT-%d]
Read [%s,PHPT-%d]
GC [0]
1 deleted
Read [%s,PHPT-%d]
bool(true)
Write [%s,PHPT-%d,]
Close [%s,PHPSESSID]
@@ -88,12 +88,10 @@ string(%d) "PHPT-%d"
string(%d) "PHPT-%d"
Open [%s,PHPSESSID]
ValidateID [%s,PHPT-%d]
Read [%s,PHPT-%d]
GC [0]
1 deleted
Read [%s,PHPT-%d]
bool(true)
Destroy [%s,PHPT-%d]
Warning: unlink(%ssession_test_PHPT-%s): No such file or directory in %ssave_handler.inc on line %d
Close [%s,PHPSESSID]
bool(true)
+8 -2
View File
@@ -130,6 +130,10 @@ static zend_always_inline uint32_t *spl_array_get_pos_ptr(HashTable *ht, spl_arr
static void spl_array_object_free_storage(zend_object *object)
{
spl_array_object *intern = spl_array_from_obj(object);
if (intern->ht_iter != (uint32_t) -1) {
zend_hash_iterator_del(intern->ht_iter);
}
zend_object_std_dtor(&intern->std);
@@ -1169,8 +1173,8 @@ zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object,
}
/* }}} */
/* {{{ proto void ArrayObject::__construct(array|object ar = array() [, int flags = 0 [, string iterator_class = "ArrayIterator"]])
proto void ArrayIterator::__construct(array|object ar = array() [, int flags = 0])
/* {{{ proto void ArrayObject::__construct([array|object ar = array() [, int flags = 0 [, string iterator_class = "ArrayIterator"]]])
proto void ArrayIterator::__construct([array|object ar = array() [, int flags = 0]])
Constructs a new array iterator from a path. */
SPL_METHOD(Array, __construct)
{
@@ -1812,6 +1816,8 @@ outexcept:
/* {{{ arginfo and function table */
ZEND_BEGIN_ARG_INFO_EX(arginfo_array___construct, 0, 0, 0)
ZEND_ARG_INFO(0, array)
ZEND_ARG_INFO(0, ar_flags)
ZEND_ARG_INFO(0, iterator_class)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_array_offsetGet, 0, 0, 1)
+16
View File
@@ -0,0 +1,16 @@
--TEST--
Bug #71153: Performance Degradation in ArrayIterator with large arrays
--FILE--
<?php
$n = 200000;
for ($i = 0; $i < $n; ++$i) {
foreach (new ArrayIterator([]) as $v) {}
}
echo "done\n";
?>
--EXPECT--
done
+3 -8
View File
@@ -3978,22 +3978,17 @@ PHP_FUNCTION(ip2long)
Converts an (IPv4) Internet network address into a string in Internet standard dotted format */
PHP_FUNCTION(long2ip)
{
/* "It's a long but it's not, PHP ints are signed */
char *ip;
size_t ip_len;
uint32_t n;
zend_ulong ip;
struct in_addr myaddr;
#ifdef HAVE_INET_PTON
char str[40];
#endif
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &ip, &ip_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &ip) == FAILURE) {
return;
}
n = strtoul(ip, NULL, 0);
myaddr.s_addr = htonl(n);
myaddr.s_addr = htonl(ip);
#ifdef HAVE_INET_PTON
if (inet_ntop(AF_INET, &myaddr, str, sizeof(str))) {
RETURN_STRING(str);
+6 -33
View File
@@ -30,6 +30,7 @@
#include "base64.h"
#include "zend_interfaces.h"
#include "info.h"
#include "php_random.h"
#if PHP_WIN32
#include "win32/winutil.h"
@@ -109,8 +110,7 @@ static int php_password_salt_to64(const char *str, const size_t str_len, const s
static int php_password_make_salt(size_t length, char *ret) /* {{{ */
{
int buffer_valid = 0;
size_t i, raw_length;
size_t raw_length;
char *buffer;
char *result;
@@ -123,37 +123,10 @@ static int php_password_make_salt(size_t length, char *ret) /* {{{ */
buffer = (char *) safe_emalloc(raw_length, 1, 1);
#if PHP_WIN32
{
BYTE *iv_b = (BYTE *) buffer;
if (php_win32_get_random_bytes(iv_b, raw_length) == SUCCESS) {
buffer_valid = 1;
}
}
#else
{
int fd, n;
size_t read_bytes = 0;
fd = open("/dev/urandom", O_RDONLY);
if (fd >= 0) {
while (read_bytes < raw_length) {
n = read(fd, buffer + read_bytes, raw_length - read_bytes);
if (n < 0) {
break;
}
read_bytes += (size_t) n;
}
close(fd);
}
if (read_bytes >= raw_length) {
buffer_valid = 1;
}
}
#endif
if (!buffer_valid) {
for (i = 0; i < raw_length; i++) {
buffer[i] ^= (char) (255.0 * php_rand() / RAND_MAX);
}
if (FAILURE == php_random_bytes_silent(buffer, raw_length)) {
php_error_docref(NULL, E_WARNING, "Unable to generate salt");
efree(buffer);
return FAILURE;
}
result = safe_emalloc(length, 1, 1);
+1 -1
View File
@@ -1330,7 +1330,7 @@ PHP_FUNCTION(stream_get_line)
/* }}} */
/* {{{ proto bool stream_set_blocking(resource socket, int mode)
/* {{{ proto bool stream_set_blocking(resource socket, bool mode)
Set blocking/non-blocking mode on a socket or stream */
PHP_FUNCTION(stream_set_blocking)
{
+2 -2
View File
@@ -1439,7 +1439,7 @@ PHPAPI zend_string *php_string_toupper(zend_string *s)
e = c + ZSTR_LEN(s);
while (c < e) {
if (!isupper(*c)) {
if (islower(*c)) {
register unsigned char *r;
zend_string *res = zend_string_alloc(ZSTR_LEN(s), 0);
@@ -1508,7 +1508,7 @@ PHPAPI zend_string *php_string_tolower(zend_string *s)
e = c + ZSTR_LEN(s);
while (c < e) {
if (!islower(*c)) {
if (isupper(*c)) {
register unsigned char *r;
zend_string *res = zend_string_alloc(ZSTR_LEN(s), 0);
+7 -5
View File
@@ -48,20 +48,22 @@ string(7) "0.0.0.0"
int(1118019956)
string(14) "66.163.161.116"
Warning: ip2long() expects exactly 1 parameter, 0 given in %s on line %d
Warning: ip2long() expects exactly 1 parameter, 0 given in %sip.php on line %d
NULL
bool(false)
bool(false)
int(1869573999)
Warning: ip2long() expects parameter 1 to be string, array given in %s on line %d
Warning: ip2long() expects parameter 1 to be string, array given in %sip.php on line %d
NULL
Warning: long2ip() expects exactly 1 parameter, 0 given in %s on line %d
Warning: long2ip() expects exactly 1 parameter, 0 given in %sip.php on line %d
NULL
string(13) "255.254.82.80"
string(7) "0.0.0.0"
Warning: long2ip() expects parameter 1 to be string, array given in %s on line %d
Warning: long2ip() expects parameter 1 to be integer, string given in %sip.php on line %d
NULL
Warning: long2ip() expects parameter 1 to be integer, array given in %sip.php on line %d
NULL
Done
+7 -5
View File
@@ -48,20 +48,22 @@ string(7) "0.0.0.0"
int(1118019956)
string(14) "66.163.161.116"
Warning: ip2long() expects exactly 1 parameter, 0 given in %s on line %d
Warning: ip2long() expects exactly 1 parameter, 0 given in %sip_x86_64.php on line %d
NULL
bool(false)
bool(false)
int(1869573999)
Warning: ip2long() expects parameter 1 to be string, array given in %s on line %d
Warning: ip2long() expects parameter 1 to be string, array given in %sip_x86_64.php on line %d
NULL
Warning: long2ip() expects exactly 1 parameter, 0 given in %s on line %d
Warning: long2ip() expects exactly 1 parameter, 0 given in %sip_x86_64.php on line %d
NULL
string(13) "255.254.82.80"
string(7) "0.0.0.0"
Warning: long2ip() expects parameter 1 to be string, array given in %s on line %d
Warning: long2ip() expects parameter 1 to be integer, string given in %sip_x86_64.php on line %d
NULL
Warning: long2ip() expects parameter 1 to be integer, array given in %sip_x86_64.php on line %d
NULL
Done
@@ -126,19 +126,19 @@ string(15) "255.255.255.246"
string(7) "0.0.0.0"
--empty array--
Error: 2 - long2ip() expects parameter 1 to be string, array given, %s(%d)
Error: 2 - long2ip() expects parameter 1 to be integer, array given, %slong2ip_variation1.php(%d)
NULL
--int indexed array--
Error: 2 - long2ip() expects parameter 1 to be string, array given, %s(%d)
Error: 2 - long2ip() expects parameter 1 to be integer, array given, %slong2ip_variation1.php(%d)
NULL
--associative array--
Error: 2 - long2ip() expects parameter 1 to be string, array given, %s(%d)
Error: 2 - long2ip() expects parameter 1 to be integer, array given, %slong2ip_variation1.php(%d)
NULL
--nested arrays--
Error: 2 - long2ip() expects parameter 1 to be string, array given, %s(%d)
Error: 2 - long2ip() expects parameter 1 to be integer, array given, %slong2ip_variation1.php(%d)
NULL
--uppercase NULL--
@@ -160,28 +160,35 @@ string(7) "0.0.0.1"
string(7) "0.0.0.0"
--empty string DQ--
string(7) "0.0.0.0"
Error: 2 - long2ip() expects parameter 1 to be integer, string given, %slong2ip_variation1.php(%d)
NULL
--empty string SQ--
string(7) "0.0.0.0"
Error: 2 - long2ip() expects parameter 1 to be integer, string given, %slong2ip_variation1.php(%d)
NULL
--string DQ--
string(7) "0.0.0.0"
Error: 2 - long2ip() expects parameter 1 to be integer, string given, %slong2ip_variation1.php(%d)
NULL
--string SQ--
string(7) "0.0.0.0"
Error: 2 - long2ip() expects parameter 1 to be integer, string given, %slong2ip_variation1.php(%d)
NULL
--mixed case string--
string(7) "0.0.0.0"
Error: 2 - long2ip() expects parameter 1 to be integer, string given, %slong2ip_variation1.php(%d)
NULL
--heredoc--
string(7) "0.0.0.0"
Error: 2 - long2ip() expects parameter 1 to be integer, string given, %slong2ip_variation1.php(%d)
NULL
--instance of classWithToString--
string(7) "0.0.0.0"
Error: 2 - long2ip() expects parameter 1 to be integer, object given, %slong2ip_variation1.php(%d)
NULL
--instance of classWithoutToString--
Error: 2 - long2ip() expects parameter 1 to be string, object given, %s(%d)
Error: 2 - long2ip() expects parameter 1 to be integer, object given, %slong2ip_variation1.php(%d)
NULL
--undefined var--
@@ -191,6 +198,6 @@ string(7) "0.0.0.0"
string(7) "0.0.0.0"
--resource--
Error: 2 - long2ip() expects parameter 1 to be string, resource given, %s(%d)
Error: 2 - long2ip() expects parameter 1 to be integer, resource given, %slong2ip_variation1.php(%d)
NULL
===DONE===
+5 -5
View File
@@ -111,7 +111,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_object, 0, 0, 2)
ZEND_ARG_INFO(0, parser)
ZEND_ARG_INFO(1, obj)
ZEND_ARG_INFO(0, obj)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_xml_set_element_handler, 0, 0, 3)
@@ -1169,7 +1169,7 @@ PHP_FUNCTION(xml_set_object)
xml_parser *parser;
zval *pind, *mythis;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ro/", &pind, &mythis) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ro", &pind, &mythis) == FAILURE) {
return;
}
@@ -1383,7 +1383,7 @@ PHP_FUNCTION(xml_set_end_namespace_decl_handler)
}
/* }}} */
/* {{{ proto int xml_parse(resource parser, string data [, int isFinal])
/* {{{ proto int xml_parse(resource parser, string data [, bool isFinal])
Start parsing an XML document */
PHP_FUNCTION(xml_parse)
{
@@ -1392,9 +1392,9 @@ PHP_FUNCTION(xml_parse)
char *data;
size_t data_len;
int ret;
zend_long isFinal = 0;
zend_bool isFinal = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &pind, &data, &data_len, &isFinal) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|b", &pind, &data, &data_len, &isFinal) == FAILURE) {
return;
}
+1 -1
View File
@@ -1622,7 +1622,7 @@ static PHP_FUNCTION(xmlwriter_end_dtd_entity)
}
/* }}} */
/* {{{ proto bool xmlwriter_write_dtd_entity(resource xmlwriter, string name, string content [, int pe [, string pubid [, string sysid [, string ndataid]]]])
/* {{{ proto bool xmlwriter_write_dtd_entity(resource xmlwriter, string name, string content [, bool pe [, string pubid [, string sysid [, string ndataid]]]])
Write full DTD Entity tag - returns FALSE on error */
static PHP_FUNCTION(xmlwriter_write_dtd_entity)
{
+9 -9
View File
@@ -142,14 +142,14 @@ PHP_FUNCTION(header_register_callback)
}
/* }}} */
static void sapi_run_header_callback(void)
static void sapi_run_header_callback(zval *callback)
{
int error;
zend_fcall_info fci;
char *callback_error = NULL;
zval retval;
if (zend_fcall_info_init(&SG(callback_func), 0, &fci, &SG(fci_cache), NULL, &callback_error) == SUCCESS) {
if (zend_fcall_info_init(callback, 0, &fci, &SG(fci_cache), NULL, &callback_error) == SUCCESS) {
fci.retval = &retval;
error = zend_call_function(&fci, &SG(fci_cache));
@@ -446,7 +446,6 @@ SAPI_API void sapi_activate(void)
SG(sapi_headers).http_status_line = NULL;
SG(sapi_headers).mimetype = NULL;
SG(headers_sent) = 0;
SG(callback_run) = 0;
ZVAL_UNDEF(&SG(callback_func));
SG(read_post_bytes) = 0;
SG(request_info).request_body = NULL;
@@ -543,8 +542,6 @@ SAPI_API void sapi_deactivate(void)
sapi_send_headers_free();
SG(sapi_started) = 0;
SG(headers_sent) = 0;
SG(callback_run) = 0;
zval_ptr_dtor(&SG(callback_func));
SG(request_info).headers_read = 0;
SG(global_request_time) = 0;
}
@@ -851,7 +848,7 @@ SAPI_API int sapi_send_headers(void)
int retval;
int ret = FAILURE;
if (SG(headers_sent) || SG(request_info).no_headers || SG(callback_run)) {
if (SG(headers_sent) || SG(request_info).no_headers) {
return SUCCESS;
}
@@ -871,9 +868,12 @@ SAPI_API int sapi_send_headers(void)
SG(sapi_headers).send_default_content_type = 0;
}
if (Z_TYPE(SG(callback_func)) != IS_UNDEF && !SG(callback_run)) {
SG(callback_run) = 1;
sapi_run_header_callback();
if (Z_TYPE(SG(callback_func)) != IS_UNDEF) {
zval cb;
ZVAL_COPY_VALUE(&cb, &SG(callback_func));
ZVAL_UNDEF(&SG(callback_func));
sapi_run_header_callback(&cb);
zval_ptr_dtor(&cb);
}
SG(headers_sent) = 1;
-1
View File
@@ -136,7 +136,6 @@ typedef struct _sapi_globals_struct {
HashTable known_post_content_types;
zval callback_func;
zend_fcall_info_cache fci_cache;
zend_bool callback_run;
} sapi_globals_struct;
-6
View File
@@ -97,9 +97,6 @@
#if HAVE_XML && HAVE_WDDX
#include "ext/wddx/php_wddx.h"
#endif
#ifdef HAVE_SQLITE
#include "ext/sqlite/php_sqlite.h"
#endif
#include "ext/com_dotnet/php_com_dotnet.h"
#ifdef HAVE_SPL
#include "ext/spl/php_spl.h"
@@ -172,9 +169,6 @@ static zend_module_entry *php_builtin_extensions[] = {
#if HAVE_XML && HAVE_WDDX
,phpext_wddx_ptr
#endif
#if HAVE_SQLITE
,phpext_sqlite_ptr
#endif
#if HAVE_SPL
,phpext_spl_ptr
#endif
+4 -4
View File
@@ -956,10 +956,6 @@ cli_server.color = On
; Default is 0, which does not produce any errors.
;intl.error_level = E_WARNING
[sqlite]
; http://php.net/sqlite.assoc-case
;sqlite.assoc_case = 0
[sqlite3]
;sqlite3.extension_dir =
@@ -1516,6 +1512,10 @@ url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
; http://php.net/session.upload-progress.min-freq
;session.upload_progress.min_freq = "1"
; Only write session data when session data is changed. Enabled by default.
; http://php.net/session.lazy-write
;session.lazy_write = On
[Assertion]
; Switch whether to compile assertions at all (to have no overhead at run-time)
; -1: Do not compile at all

Some files were not shown because too many files have changed in this diff Show More