mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
Merge branch 'master' into assert
* master: (59 commits) Improved ASSIGN_DIM handler Don't inline slow path Revert a part committted by mistake Fixed compilation warnings Fixed a bug that header value is not terminated by '\0' when accessed through getenv(). better name Improve fix for #69038 Update NEWs Fixed bug #69108 ("Segmentation fault" when (de)serializing SplObjectStorage) Added specialized versions of DO_FCALL handler: DO_ICALL - for internal functions DO_UCALL - for user functions DO_FCALL_BY_NAME - plain, most probably user, funcstions (not methods) Use cache_slot offsets instead of indexes (simplify run-time instructions) Split INIT_FCALL_BY_NAME inti INIT_FCALL_BY_NAME(CONST+STRING) and INIT_DYNAMIC_CALL(CONST-STRING|TMPVAR|CV) Support list($a, $b) = $a Avoid unnecassary check Make zend_array_destroy() to free the corresponding zend_array Eliminate check on the fast path Make current() and key() receive argument by value. Use Firebird default home folder, replace Interbase with Firebird Updated NEWS updated NEWS ... Conflicts: Zend/zend_vm_execute.h Zend/zend_vm_opcodes.c Zend/zend_vm_opcodes.h
This commit is contained in:
commit
021fd94ed1
1
NEWS
1
NEWS
@ -34,6 +34,7 @@
|
||||
. Implemented FR #55467 (phpinfo: PHP Variables with $ and single quotes). (Kalle)
|
||||
. Fixed bug #55415 (php_info produces invalid anchor names). (Kalle, Johannes)
|
||||
. Added ?? operator. (Andrea)
|
||||
. Added <=> operator. (Andrea)
|
||||
. Added \u{xxxxx} Unicode Codepoint Escape Syntax. (Andrea)
|
||||
. Fixed oversight where define() did not support arrays yet const syntax did. (Andrea, Dmitry)
|
||||
. Use "integer" and "float" instead of "long" and "double" in ZPP, type hint and conversion error messages. (Andrea)
|
||||
|
@ -398,6 +398,8 @@ Other
|
||||
. Added \u{xxxxxx} Unicode Codepoint Escape Syntax for double-quoted strings
|
||||
and heredocs.
|
||||
. define() now supports arrays as constant values, fixing an oversight where define() did not support arrays yet const syntax did.
|
||||
. Added the comparison operator (<=>), aka the spaceship operator.
|
||||
(RFC: https://wiki.php.net/rfc/combined-comparison-operator)
|
||||
|
||||
========================================
|
||||
3. Changes in SAPI modules
|
||||
|
18
Zend/tests/bug69092.2.phpt
Normal file
18
Zend/tests/bug69092.2.phpt
Normal file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Bug #69092-2 (Declare Encoding Compile Check Wrong) - multibyte off
|
||||
--INI--
|
||||
zend.multibyte=0
|
||||
--FILE--
|
||||
<?php
|
||||
echo "Hi";
|
||||
|
||||
function foo() {
|
||||
declare(encoding="UTF-8");
|
||||
}
|
||||
|
||||
echo "Bye"
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: declare(encoding=...) ignored because Zend multibyte feature is turned off by settings in %s on line %d
|
||||
|
||||
Fatal error: Encoding declaration pragma must be the very first statement in the script in %s on line %d
|
22
Zend/tests/bug69092.phpt
Normal file
22
Zend/tests/bug69092.phpt
Normal file
@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
Bug #69092 (Declare Encoding Compile Check Wrong)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("mbstring")) {
|
||||
die("skip Requires mbstring extension");
|
||||
}
|
||||
?>
|
||||
--INI--
|
||||
zend.multibyte=On
|
||||
--FILE--
|
||||
<?php
|
||||
echo "Hi";
|
||||
|
||||
function foo() {
|
||||
declare(encoding="utf-8");
|
||||
}
|
||||
|
||||
echo "Bye"
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Encoding declaration pragma must be the very first statement in the script in %s on line %d
|
11
Zend/tests/gc_034.phpt
Normal file
11
Zend/tests/gc_034.phpt
Normal file
@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
GC 034: GC in request shutdown and resource list destroy
|
||||
--FILE--
|
||||
<?php
|
||||
/* run with valgrind */
|
||||
$a = array(fopen(__FILE__, 'r'));
|
||||
$a[] = &$a;
|
||||
?>
|
||||
==DONE==
|
||||
--EXPECT--
|
||||
==DONE==
|
56
Zend/tests/list_self_assign.phpt
Normal file
56
Zend/tests/list_self_assign.phpt
Normal file
@ -0,0 +1,56 @@
|
||||
--TEST--
|
||||
Test variable occuring on both LHS and RHS of list()
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = [1, 2, 3];
|
||||
list($a, $b, $c) = $a;
|
||||
var_dump($a, $b, $c);
|
||||
|
||||
$b = [1, 2, 3];
|
||||
list($a, $b, $c) = $b;
|
||||
var_dump($a, $b, $c);
|
||||
|
||||
$c = [1, 2, 3];
|
||||
list($a, $b, $c) = $c;
|
||||
var_dump($a, $b, $c);
|
||||
|
||||
$a = [[1, 2], 3];
|
||||
list(list($a, $b), $c) = $a;
|
||||
var_dump($a, $b, $c);
|
||||
|
||||
$b = [[1, 2], 3];
|
||||
list(list($a, $b), $c) = $b;
|
||||
var_dump($a, $b, $c);
|
||||
|
||||
$b = [1, [2, 3]];
|
||||
list($a, list($b, $c)) = $b;
|
||||
var_dump($a, $b, $c);
|
||||
|
||||
$c = [1, [2, 3]];
|
||||
list($a, list($b, $c)) = $c;
|
||||
var_dump($a, $b, $c);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
33
Zend/zend.c
33
Zend/zend.c
@ -494,22 +494,28 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{
|
||||
static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{{ */
|
||||
{
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
|
||||
zend_startup_constants();
|
||||
zend_copy_constants(EG(zend_constants), GLOBAL_CONSTANTS_TABLE);
|
||||
zend_init_rsrc_plist();
|
||||
zend_init_exception_op();
|
||||
EG(lambda_count) = 0;
|
||||
ZVAL_UNDEF(&EG(user_error_handler));
|
||||
ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
EG(in_autoload) = NULL;
|
||||
EG(current_execute_data) = NULL;
|
||||
EG(current_module) = NULL;
|
||||
EG(exit_status) = 0;
|
||||
executor_globals->lambda_count = 0;
|
||||
ZVAL_UNDEF(&executor_globals->user_error_handler);
|
||||
ZVAL_UNDEF(&executor_globals->user_exception_handler);
|
||||
executor_globals->in_autoload = NULL;
|
||||
executor_globals->current_execute_data = NULL;
|
||||
executor_globals->current_module = NULL;
|
||||
executor_globals->exit_status = 0;
|
||||
#if XPFPA_HAVE_CW
|
||||
EG(saved_fpu_cw) = 0;
|
||||
executor_globals->saved_fpu_cw = 0;
|
||||
#endif
|
||||
EG(saved_fpu_cw_ptr) = NULL;
|
||||
EG(active) = 0;
|
||||
executor_globals->saved_fpu_cw_ptr = NULL;
|
||||
executor_globals->active = 0;
|
||||
executor_globals->bailout = NULL;
|
||||
executor_globals->error_handling = EH_NORMAL;
|
||||
executor_globals->exception_class = NULL;
|
||||
executor_globals->exception = NULL;
|
||||
executor_globals->objects_store.object_buckets = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -690,9 +696,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
|
||||
ini_scanner_globals_ctor(&ini_scanner_globals);
|
||||
php_scanner_globals_ctor(&language_scanner_globals);
|
||||
zend_set_default_compile_time_values();
|
||||
ZVAL_UNDEF(&EG(user_error_handler));
|
||||
ZVAL_UNDEF(&EG(user_exception_handler));
|
||||
#endif
|
||||
EG(error_reporting) = E_ALL & ~E_NOTICE;
|
||||
|
||||
zend_interned_strings_init();
|
||||
zend_startup_builtin_functions();
|
||||
@ -921,14 +926,14 @@ ZEND_API void zend_deactivate(void) /* {{{ */
|
||||
shutdown_compiler();
|
||||
} zend_end_try();
|
||||
|
||||
zend_destroy_rsrc_list(&EG(regular_list));
|
||||
|
||||
#if ZEND_DEBUG
|
||||
if (GC_G(gc_enabled) && !CG(unclean_shutdown)) {
|
||||
gc_collect_cycles();
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_destroy_rsrc_list(&EG(regular_list));
|
||||
|
||||
#if GC_BENCH
|
||||
fprintf(stderr, "GC Statistics\n");
|
||||
fprintf(stderr, "-------------\n");
|
||||
|
@ -3915,7 +3915,7 @@ ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_functi
|
||||
zend_string *name;
|
||||
|
||||
if (f->common.type != ZEND_USER_FUNCTION ||
|
||||
*(f->op_array.refcount) < 2 ||
|
||||
(f->op_array.refcount && *(f->op_array.refcount) < 2) ||
|
||||
!f->common.scope ||
|
||||
!f->common.scope->trait_aliases) {
|
||||
return f->common.function_name;
|
||||
|
@ -890,7 +890,6 @@ static void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int ind
|
||||
|
||||
static void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent)
|
||||
{
|
||||
zval *zv;
|
||||
zend_ast_decl *decl;
|
||||
int p, pl, pr;
|
||||
const char *op;
|
||||
|
@ -1227,7 +1227,7 @@ ZEND_FUNCTION(get_class_methods)
|
||||
zend_binary_strcasecmp(key->val, key->len, mptr->common.function_name->val, len) == 0) {
|
||||
|
||||
if (mptr->type == ZEND_USER_FUNCTION &&
|
||||
*mptr->op_array.refcount > 1 &&
|
||||
(!mptr->op_array.refcount || *mptr->op_array.refcount > 1) &&
|
||||
!same_name(key, mptr->common.function_name)) {
|
||||
ZVAL_STR_COPY(&method_name, zend_find_alias_name(mptr->common.scope, key));
|
||||
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
|
||||
@ -1936,7 +1936,9 @@ ZEND_FUNCTION(create_function)
|
||||
zend_error(E_ERROR, "Unexpected inconsistency in create_function()");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
(*func->refcount)++;
|
||||
if (func->refcount) {
|
||||
(*func->refcount)++;
|
||||
}
|
||||
static_variables = func->static_variables;
|
||||
func->static_variables = NULL;
|
||||
zend_hash_str_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1);
|
||||
@ -2256,6 +2258,9 @@ ZEND_FUNCTION(debug_print_backtrace)
|
||||
skip->prev_execute_data->func &&
|
||||
ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
|
||||
skip = skip->prev_execute_data;
|
||||
}
|
||||
@ -2451,6 +2456,9 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
|
||||
skip->prev_execute_data->func &&
|
||||
ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
|
||||
skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
|
||||
skip = skip->prev_execute_data;
|
||||
}
|
||||
|
@ -63,6 +63,9 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */
|
||||
/* destruct the function also, then - we have allocated it in get_method */
|
||||
zend_string_release(func->internal_function.function_name);
|
||||
efree(func);
|
||||
#if ZEND_DEBUG
|
||||
execute_data->func = NULL;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -499,7 +502,9 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
|
||||
zend_hash_apply_with_arguments(static_variables, zval_copy_static_var, 1, closure->func.op_array.static_variables);
|
||||
}
|
||||
closure->func.op_array.run_time_cache = NULL;
|
||||
(*closure->func.op_array.refcount)++;
|
||||
if (closure->func.op_array.refcount) {
|
||||
(*closure->func.op_array.refcount)++;
|
||||
}
|
||||
} else {
|
||||
/* verify that we aren't binding internal function to a wrong scope */
|
||||
if(func->common.scope != NULL) {
|
||||
|
@ -52,15 +52,16 @@
|
||||
|
||||
static inline void zend_alloc_cache_slot(uint32_t literal) {
|
||||
zend_op_array *op_array = CG(active_op_array);
|
||||
Z_CACHE_SLOT(op_array->literals[literal]) = op_array->last_cache_slot++;
|
||||
Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size;
|
||||
op_array->cache_size += sizeof(void*);
|
||||
}
|
||||
|
||||
#define POLYMORPHIC_CACHE_SLOT_SIZE 2
|
||||
|
||||
static inline void zend_alloc_polymorphic_cache_slot(uint32_t literal) {
|
||||
zend_op_array *op_array = CG(active_op_array);
|
||||
Z_CACHE_SLOT(op_array->literals[literal]) = op_array->last_cache_slot;
|
||||
op_array->last_cache_slot += POLYMORPHIC_CACHE_SLOT_SIZE;
|
||||
Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size;
|
||||
op_array->cache_size += POLYMORPHIC_CACHE_SLOT_SIZE * sizeof(void*);
|
||||
}
|
||||
|
||||
ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);
|
||||
@ -863,9 +864,13 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */
|
||||
if (function->type == ZEND_USER_FUNCTION) {
|
||||
zend_op_array *op_array = &function->op_array;
|
||||
|
||||
(*op_array->refcount)++;
|
||||
if (op_array->refcount) {
|
||||
(*op_array->refcount)++;
|
||||
}
|
||||
if (op_array->static_variables) {
|
||||
op_array->static_variables = zend_array_dup(op_array->static_variables);
|
||||
if (!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_REFCOUNT(op_array->static_variables)++;
|
||||
}
|
||||
}
|
||||
op_array->run_time_cache = NULL;
|
||||
} else if (function->type == ZEND_INTERNAL_FUNCTION) {
|
||||
@ -908,7 +913,9 @@ ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opli
|
||||
}
|
||||
return FAILURE;
|
||||
} else {
|
||||
(*function->op_array.refcount)++;
|
||||
if (function->op_array.refcount) {
|
||||
(*function->op_array.refcount)++;
|
||||
}
|
||||
function->op_array.static_variables = NULL; /* NULL out the unbound function */
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -2310,6 +2317,50 @@ zend_bool zend_is_assign_to_self(zend_ast *var_ast, zend_ast *expr_ast) /* {{{ *
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Detects if list($a, $b, $c) contains variable with given name */
|
||||
zend_bool zend_list_has_assign_to(zend_ast *list_ast, zend_string *name) /* {{{ */
|
||||
{
|
||||
zend_ast_list *list = zend_ast_get_list(list_ast);
|
||||
uint32_t i;
|
||||
for (i = 0; i < list->children; i++) {
|
||||
zend_ast *var_ast = list->child[i];
|
||||
if (!var_ast) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Recursively check nested list()s */
|
||||
if (var_ast->kind == ZEND_AST_LIST && zend_list_has_assign_to(var_ast, name)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (var_ast->kind == ZEND_AST_VAR && var_ast->child[0]->kind == ZEND_AST_ZVAL) {
|
||||
zend_string *var_name = zval_get_string(zend_ast_get_zval(var_ast->child[0]));
|
||||
zend_bool result = zend_string_equals(var_name, name);
|
||||
zend_string_release(var_name);
|
||||
if (result) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* Detects patterns like list($a, $b, $c) = $a */
|
||||
zend_bool zend_list_has_assign_to_self(zend_ast *list_ast, zend_ast *expr_ast) /* {{{ */
|
||||
{
|
||||
/* Only check simple variables on the RHS, as only CVs cause issues with this. */
|
||||
if (expr_ast->kind == ZEND_AST_VAR && expr_ast->child[0]->kind == ZEND_AST_ZVAL) {
|
||||
zend_string *name = zval_get_string(zend_ast_get_zval(expr_ast->child[0]));
|
||||
zend_bool result = zend_list_has_assign_to(list_ast, name);
|
||||
zend_string_release(name);
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
|
||||
{
|
||||
zend_ast *var_ast = ast->child[0];
|
||||
@ -2359,7 +2410,13 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
|
||||
zend_emit_op_data(&expr_node);
|
||||
return;
|
||||
case ZEND_AST_LIST:
|
||||
zend_compile_expr(&expr_node, expr_ast);
|
||||
if (zend_list_has_assign_to_self(var_ast, expr_ast)) {
|
||||
/* list($a, $b) = $a should evaluate the right $a first */
|
||||
zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
|
||||
} else {
|
||||
zend_compile_expr(&expr_node, expr_ast);
|
||||
}
|
||||
|
||||
zend_compile_list_assign(result, var_ast, &expr_node);
|
||||
return;
|
||||
EMPTY_SWITCH_DEFAULT_CASE();
|
||||
@ -2560,6 +2617,31 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_uchar zend_get_call_op(zend_uchar init_op, zend_function *fbc) /* {{{ */
|
||||
{
|
||||
if (fbc) {
|
||||
if (fbc->type == ZEND_INTERNAL_FUNCTION) {
|
||||
if (!zend_execute_internal &&
|
||||
!fbc->common.scope &&
|
||||
!(fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED|ZEND_ACC_HAS_TYPE_HINTS))) {
|
||||
return ZEND_DO_ICALL;
|
||||
}
|
||||
} else {
|
||||
if (zend_execute_ex == execute_ex &&
|
||||
!(fbc->common.fn_flags & ZEND_ACC_GENERATOR)) {
|
||||
return ZEND_DO_UCALL;
|
||||
}
|
||||
}
|
||||
} else if (zend_execute_ex == execute_ex &&
|
||||
!zend_execute_internal &&
|
||||
(init_op == ZEND_INIT_FCALL_BY_NAME ||
|
||||
init_op == ZEND_INIT_NS_FCALL_BY_NAME)) {
|
||||
return ZEND_DO_FCALL_BY_NAME;
|
||||
}
|
||||
return ZEND_DO_FCALL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *fbc) /* {{{ */
|
||||
{
|
||||
zend_op *opline;
|
||||
@ -2579,7 +2661,7 @@ void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *
|
||||
}
|
||||
|
||||
call_flags = (opline->opcode == ZEND_NEW ? ZEND_CALL_CTOR : 0);
|
||||
opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
|
||||
opline = zend_emit_op(result, zend_get_call_op(opline->opcode, fbc), NULL, NULL);
|
||||
opline->op1.num = call_flags;
|
||||
|
||||
zend_do_extended_fcall_end();
|
||||
@ -2616,16 +2698,17 @@ void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast) /
|
||||
void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */
|
||||
{
|
||||
zend_op *opline = get_next_op(CG(active_op_array));
|
||||
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
|
||||
SET_UNUSED(opline->op1);
|
||||
if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) {
|
||||
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
|
||||
opline->op2_type = IS_CONST;
|
||||
opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
|
||||
Z_STR(name_node->u.constant));
|
||||
zend_alloc_cache_slot(opline->op2.constant);
|
||||
} else {
|
||||
opline->opcode = ZEND_INIT_DYNAMIC_CALL;
|
||||
SET_NODE(opline->op2, name_node);
|
||||
}
|
||||
SET_UNUSED(opline->op1);
|
||||
|
||||
zend_compile_call_common(result, args_ast, NULL);
|
||||
}
|
||||
@ -3146,6 +3229,12 @@ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_
|
||||
zend_hash_init(CG(active_op_array)->static_variables, 8, NULL, ZVAL_PTR_DTOR, 0);
|
||||
}
|
||||
|
||||
if (GC_REFCOUNT(CG(active_op_array)->static_variables) > 1) {
|
||||
if (!(GC_FLAGS(CG(active_op_array)->static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_REFCOUNT(CG(active_op_array)->static_variables)--;
|
||||
}
|
||||
CG(active_op_array)->static_variables = zend_array_dup(CG(active_op_array)->static_variables);
|
||||
}
|
||||
zend_hash_update(CG(active_op_array)->static_variables, Z_STR(var_node.u.constant), value);
|
||||
|
||||
opline = zend_emit_op(&result, by_ref ? ZEND_FETCH_W : ZEND_FETCH_R, &var_node, NULL);
|
||||
@ -3846,16 +3935,26 @@ void zend_compile_declare(zend_ast *ast) /* {{{ */
|
||||
ZVAL_COPY_VALUE(&CG(declarables).ticks, &value_zv);
|
||||
zval_dtor(&value_zv);
|
||||
} else if (zend_string_equals_literal_ci(name, "encoding")) {
|
||||
uint32_t i = 0;
|
||||
zend_bool valid = 0;
|
||||
/* Encoding declaration was already handled during parsing. Here we
|
||||
* only check that it is the first statement in the file. */
|
||||
uint32_t num = CG(active_op_array)->last;
|
||||
while (num > 0 &&
|
||||
(CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT ||
|
||||
CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) {
|
||||
--num;
|
||||
}
|
||||
zend_ast_list *file_ast = zend_ast_get_list(CG(ast));
|
||||
|
||||
if (num > 0) {
|
||||
/* Check to see if this declare is preceeded only by declare statements */
|
||||
while (valid == 0 && i < file_ast->children) {
|
||||
if (file_ast->child[i] == ast) {
|
||||
valid = 1;
|
||||
} else if (file_ast->child[i] == NULL) {
|
||||
/* Empty statements are not allowed prior to a declare */
|
||||
break;
|
||||
} else if (file_ast->child[i]->kind != ZEND_AST_DECLARE) {
|
||||
/* declares can only be preceeded by other declares */
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (valid != 1) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be "
|
||||
"the very first statement in the script");
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ struct _zend_op_array {
|
||||
int last_literal;
|
||||
zval *literals;
|
||||
|
||||
int last_cache_slot;
|
||||
int cache_size;
|
||||
void **run_time_cache;
|
||||
|
||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||
@ -718,6 +718,7 @@ ZEND_API zend_bool zend_is_compiling(void);
|
||||
ZEND_API char *zend_make_compiled_string_description(const char *name);
|
||||
ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers);
|
||||
uint32_t zend_get_class_fetch_type(zend_string *name);
|
||||
ZEND_API zend_uchar zend_get_call_op(zend_uchar init_op, zend_function *fbc);
|
||||
|
||||
typedef zend_bool (*zend_auto_global_callback)(zend_string *name);
|
||||
typedef struct _zend_auto_global {
|
||||
|
@ -511,22 +511,19 @@ static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *v
|
||||
}
|
||||
|
||||
/* this should modify object only if it's empty */
|
||||
static inline int make_real_object(zval **object_ptr)
|
||||
static inline int make_real_object(zval *object)
|
||||
{
|
||||
zval *object = *object_ptr;
|
||||
|
||||
ZVAL_DEREF(object);
|
||||
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE)
|
||||
|| (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
|
||||
if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE)) {
|
||||
/* nothing to destroy */
|
||||
} else if (EXPECTED((Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
|
||||
zval_ptr_dtor_nogc(object);
|
||||
object_init(object);
|
||||
zend_error(E_WARNING, "Creating default object from empty value");
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
object_init(object);
|
||||
zend_error(E_WARNING, "Creating default object from empty value");
|
||||
}
|
||||
*object_ptr = object;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -933,7 +930,7 @@ static zend_always_inline void zend_assign_to_object(zval *retval, zval *object,
|
||||
zend_object *zobj = Z_OBJ_P(object);
|
||||
zval *property;
|
||||
|
||||
if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
|
||||
if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
|
||||
property = OBJ_PROP(zobj, prop_offset);
|
||||
if (Z_TYPE_P(property) != IS_UNDEF) {
|
||||
fast_assign:
|
||||
@ -1166,6 +1163,12 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d
|
||||
} else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
|
||||
ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
|
||||
ht = EX(func)->op_array.static_variables;
|
||||
if (GC_REFCOUNT(ht) > 1) {
|
||||
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_REFCOUNT(ht)--;
|
||||
}
|
||||
EX(func)->op_array.static_variables = ht = zend_array_dup(ht);
|
||||
}
|
||||
} else {
|
||||
ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL);
|
||||
if (!EX(symbol_table)) {
|
||||
@ -1572,7 +1575,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
|
||||
zend_object *zobj = Z_OBJ_P(container);
|
||||
zval *retval;
|
||||
|
||||
if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
|
||||
if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
|
||||
retval = OBJ_PROP(zobj, prop_offset);
|
||||
if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
|
||||
ZVAL_INDIRECT(result, retval);
|
||||
@ -1688,7 +1691,6 @@ ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{
|
||||
{
|
||||
if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
|
||||
zend_array_destroy(symbol_table);
|
||||
efree_size(symbol_table, sizeof(zend_array));
|
||||
} else {
|
||||
/* clean before putting into the cache, since clean
|
||||
could call dtors, which could use cached hash */
|
||||
@ -1737,7 +1739,7 @@ void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
|
||||
* +----------------------------------------+
|
||||
*/
|
||||
|
||||
static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
|
||||
static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, int check_this) /* {{{ */
|
||||
{
|
||||
uint32_t first_extra_arg, num_args;
|
||||
ZEND_ASSERT(EX(func) == (zend_function*)op_array);
|
||||
@ -1793,13 +1795,14 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
|
||||
} while (var != end);
|
||||
}
|
||||
|
||||
if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
|
||||
if (check_this && op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
|
||||
ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This)));
|
||||
GC_REFCOUNT(Z_OBJ(EX(This)))++;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(!op_array->run_time_cache)) {
|
||||
op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
|
||||
op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
|
||||
memset(op_array->run_time_cache, 0, op_array->cache_size);
|
||||
}
|
||||
EX_LOAD_RUN_TIME_CACHE(op_array);
|
||||
EX_LOAD_LITERALS(op_array);
|
||||
@ -1824,7 +1827,8 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
|
||||
}
|
||||
|
||||
if (!op_array->run_time_cache) {
|
||||
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
|
||||
op_array->run_time_cache = emalloc(op_array->cache_size);
|
||||
memset(op_array->run_time_cache, 0, op_array->cache_size);
|
||||
}
|
||||
EX_LOAD_RUN_TIME_CACHE(op_array);
|
||||
EX_LOAD_LITERALS(op_array);
|
||||
@ -1901,10 +1905,11 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
|
||||
|
||||
if (!op_array->run_time_cache) {
|
||||
if (op_array->function_name) {
|
||||
op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
|
||||
op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
|
||||
} else {
|
||||
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
|
||||
op_array->run_time_cache = emalloc(op_array->cache_size);
|
||||
}
|
||||
memset(op_array->run_time_cache, 0, op_array->cache_size);
|
||||
}
|
||||
EX_LOAD_RUN_TIME_CACHE(op_array);
|
||||
EX_LOAD_LITERALS(op_array);
|
||||
@ -1958,7 +1963,7 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data
|
||||
|
||||
EX(symbol_table) = NULL;
|
||||
|
||||
i_init_func_execute_data(execute_data, op_array, return_value);
|
||||
i_init_func_execute_data(execute_data, op_array, return_value, 1);
|
||||
|
||||
return execute_data;
|
||||
}
|
||||
@ -2014,7 +2019,7 @@ static zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call,
|
||||
|
||||
static zend_always_inline void zend_vm_stack_extend_call_frame(zend_execute_data **call, uint32_t passed_args, uint32_t additional_args) /* {{{ */
|
||||
{
|
||||
if (EXPECTED(EG(vm_stack_end) - EG(vm_stack_top) > additional_args)) {
|
||||
if (EXPECTED((uint32_t)(EG(vm_stack_end) - EG(vm_stack_top)) > additional_args)) {
|
||||
EG(vm_stack_top) += additional_args;
|
||||
} else {
|
||||
*call = zend_vm_stack_copy_call_frame(*call, passed_args, additional_args);
|
||||
|
@ -256,21 +256,25 @@ ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
|
||||
ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table);
|
||||
void zend_free_compiled_variables(zend_execute_data *execute_data);
|
||||
|
||||
#define CACHE_ADDR(num) \
|
||||
((void**)((char*)EX_RUN_TIME_CACHE() + (num)))
|
||||
|
||||
#define CACHED_PTR(num) \
|
||||
EX_RUN_TIME_CACHE()[(num)]
|
||||
((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[0]
|
||||
|
||||
#define CACHE_PTR(num, ptr) do { \
|
||||
EX_RUN_TIME_CACHE()[(num)] = (ptr); \
|
||||
((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[0] = (ptr); \
|
||||
} while (0)
|
||||
|
||||
#define CACHED_POLYMORPHIC_PTR(num, ce) \
|
||||
((EX_RUN_TIME_CACHE()[(num)] == (ce)) ? \
|
||||
EX_RUN_TIME_CACHE()[(num) + 1] : \
|
||||
((((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[0] == (void*)(ce)) ? \
|
||||
((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[1] : \
|
||||
NULL)
|
||||
|
||||
#define CACHE_POLYMORPHIC_PTR(num, ce, ptr) do { \
|
||||
EX_RUN_TIME_CACHE()[(num)] = (ce); \
|
||||
EX_RUN_TIME_CACHE()[(num) + 1] = (ptr); \
|
||||
void **slot = (void**)((char*)EX_RUN_TIME_CACHE() + (num)); \
|
||||
slot[0] = (ce); \
|
||||
slot[1] = (ptr); \
|
||||
} while (0)
|
||||
|
||||
#define CACHED_PTR_EX(slot) \
|
||||
|
@ -595,8 +595,9 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas
|
||||
if (Z_REFCOUNTED_P(p)) Z_SET_REFCOUNT_P(p, refcount);
|
||||
} else if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
|
||||
zval tmp;
|
||||
SEPARATE_ZVAL_NOREF(p);
|
||||
|
||||
if (inline_change) {
|
||||
SEPARATE_ZVAL_NOREF(p);
|
||||
}
|
||||
zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope);
|
||||
if (inline_change) {
|
||||
zend_ast_destroy_and_free(Z_ASTVAL_P(p));
|
||||
@ -690,7 +691,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
|
||||
EG(current_execute_data) = &dummy_execute_data;
|
||||
} else if (EG(current_execute_data)->func &&
|
||||
ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
|
||||
EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL) {
|
||||
EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL &&
|
||||
EG(current_execute_data)->opline->opcode != ZEND_DO_ICALL &&
|
||||
EG(current_execute_data)->opline->opcode != ZEND_DO_UCALL &&
|
||||
EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL_BY_NAME) {
|
||||
/* Insert fake frame in case of include or magic calls */
|
||||
dummy_execute_data = *EG(current_execute_data);
|
||||
dummy_execute_data.prev_execute_data = EG(current_execute_data);
|
||||
|
@ -236,7 +236,9 @@ ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array
|
||||
zend_op_array *op_array_copy = (zend_op_array*)emalloc(sizeof(zend_op_array));
|
||||
*op_array_copy = *op_array;
|
||||
|
||||
(*op_array->refcount)++;
|
||||
if (op_array->refcount) {
|
||||
(*op_array->refcount)++;
|
||||
}
|
||||
op_array->run_time_cache = NULL;
|
||||
if (op_array->static_variables) {
|
||||
ALLOC_HASHTABLE(op_array_copy->static_variables);
|
||||
|
@ -1113,7 +1113,7 @@ ZEND_API void zend_array_destroy(HashTable *ht)
|
||||
/* In some rare cases destructors of regular arrays may be changed */
|
||||
if (UNEXPECTED(ht->pDestructor != ZVAL_PTR_DTOR)) {
|
||||
zend_hash_destroy(ht);
|
||||
return;
|
||||
goto free_ht;
|
||||
}
|
||||
|
||||
p = ht->arData;
|
||||
@ -1122,9 +1122,7 @@ ZEND_API void zend_array_destroy(HashTable *ht)
|
||||
|
||||
if (ht->u.flags & HASH_FLAG_PACKED) {
|
||||
do {
|
||||
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
|
||||
i_zval_ptr_dtor(&p->val ZEND_FILE_LINE_CC);
|
||||
}
|
||||
i_zval_ptr_dtor(&p->val ZEND_FILE_LINE_CC);
|
||||
} while (++p != end);
|
||||
} else {
|
||||
do {
|
||||
@ -1139,9 +1137,11 @@ ZEND_API void zend_array_destroy(HashTable *ht)
|
||||
zend_hash_iterators_remove(ht);
|
||||
SET_INCONSISTENT(HT_DESTROYED);
|
||||
} else if (EXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
|
||||
return;
|
||||
goto free_ht;
|
||||
}
|
||||
pefree(ht->arData, ht->u.flags & HASH_FLAG_PERSISTENT);
|
||||
free_ht:
|
||||
FREE_HASHTABLE(ht);
|
||||
}
|
||||
|
||||
ZEND_API void zend_hash_clean(HashTable *ht)
|
||||
|
@ -934,7 +934,9 @@ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
|
||||
|
||||
/* destruct the function also, then - we have allocated it in get_method */
|
||||
efree_size(func, sizeof(zend_internal_function));
|
||||
#if ZEND_DEBUG
|
||||
execute_data->func = NULL;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1155,7 +1157,9 @@ ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{
|
||||
|
||||
/* destruct the function also, then - we have allocated it in get_method */
|
||||
efree_size(func, sizeof(zend_internal_function));
|
||||
#if ZEND_DEBUG
|
||||
execute_data->func = NULL;
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -55,7 +55,6 @@ ZEND_API void zend_object_std_dtor(zend_object *object)
|
||||
|
||||
if (object->properties) {
|
||||
zend_array_destroy(object->properties);
|
||||
FREE_HASHTABLE(object->properties);
|
||||
}
|
||||
count = object->ce->default_properties_count;
|
||||
for (i = 0; i < count; i++) {
|
||||
|
@ -91,7 +91,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
|
||||
op_array->literals = NULL;
|
||||
|
||||
op_array->run_time_cache = NULL;
|
||||
op_array->last_cache_slot = 0;
|
||||
op_array->cache_size = 0;
|
||||
|
||||
memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*));
|
||||
|
||||
@ -130,7 +130,8 @@ ZEND_API void zend_function_dtor(zval *zv)
|
||||
|
||||
ZEND_API void zend_cleanup_op_array_data(zend_op_array *op_array)
|
||||
{
|
||||
if (op_array->static_variables) {
|
||||
if (op_array->static_variables &&
|
||||
!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
zend_hash_clean(op_array->static_variables);
|
||||
}
|
||||
}
|
||||
@ -317,16 +318,18 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
|
||||
zval *end;
|
||||
uint32_t i;
|
||||
|
||||
if (op_array->static_variables) {
|
||||
zend_hash_destroy(op_array->static_variables);
|
||||
FREE_HASHTABLE(op_array->static_variables);
|
||||
if (op_array->static_variables &&
|
||||
!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
if (--GC_REFCOUNT(op_array->static_variables) == 0) {
|
||||
zend_array_destroy(op_array->static_variables);
|
||||
}
|
||||
}
|
||||
|
||||
if (op_array->run_time_cache && !op_array->function_name) {
|
||||
efree(op_array->run_time_cache);
|
||||
}
|
||||
|
||||
if (--(*op_array->refcount)>0) {
|
||||
if (!op_array->refcount || --(*op_array->refcount)>0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2870,6 +2870,38 @@ ZEND_API const char* zend_memnrstr_ex(const char *haystack, const char *needle,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#if !ZEND_DVAL_TO_LVAL_CAST_OK
|
||||
# if SIZEOF_ZEND_LONG == 4
|
||||
ZEND_API zend_long zend_dval_to_lval_slow(double d)
|
||||
{
|
||||
double two_pow_32 = pow(2., 32.),
|
||||
dmod;
|
||||
|
||||
dmod = fmod(d, two_pow_32);
|
||||
if (dmod < 0) {
|
||||
/* we're going to make this number positive; call ceil()
|
||||
* to simulate rounding towards 0 of the negative number */
|
||||
dmod = ceil(dmod);// + two_pow_32;
|
||||
}
|
||||
return (zend_long)(zend_ulong)dmod;
|
||||
}
|
||||
#else
|
||||
ZEND_API zend_long zend_dval_to_lval_slow(double d)
|
||||
{
|
||||
double two_pow_64 = pow(2., 64.),
|
||||
dmod;
|
||||
|
||||
dmod = fmod(d, two_pow_64);
|
||||
if (dmod < 0) {
|
||||
/* no need to call ceil; original double must have had no
|
||||
* fractional part, hence dmod does not have one either */
|
||||
dmod += two_pow_64;
|
||||
}
|
||||
return (zend_long)(zend_ulong)dmod;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -108,41 +108,15 @@ static zend_always_inline zend_long zend_dval_to_lval(double d)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#elif SIZEOF_ZEND_LONG == 4
|
||||
static zend_always_inline zend_long zend_dval_to_lval(double d)
|
||||
{
|
||||
if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
|
||||
return 0;
|
||||
} else if (!ZEND_DOUBLE_FITS_LONG(d)) {
|
||||
double two_pow_32 = pow(2., 32.),
|
||||
dmod;
|
||||
|
||||
dmod = fmod(d, two_pow_32);
|
||||
if (dmod < 0) {
|
||||
/* we're going to make this number positive; call ceil()
|
||||
* to simulate rounding towards 0 of the negative number */
|
||||
dmod = ceil(dmod) + two_pow_32;
|
||||
}
|
||||
return (zend_long)(zend_ulong)dmod;
|
||||
}
|
||||
return (zend_long)d;
|
||||
}
|
||||
#else
|
||||
ZEND_API zend_long zend_dval_to_lval_slow(double d);
|
||||
|
||||
static zend_always_inline zend_long zend_dval_to_lval(double d)
|
||||
{
|
||||
if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
|
||||
return 0;
|
||||
} else if (!ZEND_DOUBLE_FITS_LONG(d)) {
|
||||
double two_pow_64 = pow(2., 64.),
|
||||
dmod;
|
||||
|
||||
dmod = fmod(d, two_pow_64);
|
||||
if (dmod < 0) {
|
||||
/* no need to call ceil; original double must have had no
|
||||
* fractional part, hence dmod does not have one either */
|
||||
dmod += two_pow_64;
|
||||
}
|
||||
return (zend_long)(zend_ulong)dmod;
|
||||
return zend_dval_to_lval_slow(d);
|
||||
}
|
||||
return (zend_long)d;
|
||||
}
|
||||
|
@ -345,6 +345,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
|
||||
#define IS_STR_CONSTANT (1<<3) /* constant index */
|
||||
#define IS_STR_CONSTANT_UNQUALIFIED (1<<4) /* the same as IS_CONSTANT_UNQUALIFIED */
|
||||
|
||||
/* array flags */
|
||||
#define IS_ARRAY_IMMUTABLE (1<<1) /* the same as IS_TYPE_IMMUTABLE */
|
||||
|
||||
/* object flags (zval.value->gc.u.flags) */
|
||||
#define IS_OBJ_APPLY_COUNT 0x07
|
||||
#define IS_OBJ_DESTRUCTOR_CALLED (1<<3)
|
||||
|
@ -46,7 +46,6 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
|
||||
GC_TYPE(arr) = IS_NULL;
|
||||
GC_REMOVE_FROM_BUFFER(arr);
|
||||
zend_array_destroy(arr);
|
||||
efree_size(arr, sizeof(zend_array));
|
||||
break;
|
||||
}
|
||||
case IS_CONSTANT_AST: {
|
||||
@ -102,7 +101,6 @@ ZEND_API void _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE_LINE_DC)
|
||||
GC_TYPE(arr) = IS_NULL;
|
||||
GC_REMOVE_FROM_BUFFER(arr);
|
||||
zend_array_destroy(arr);
|
||||
efree_size(arr, sizeof(zend_array));
|
||||
break;
|
||||
}
|
||||
case IS_CONSTANT_AST: {
|
||||
|
@ -366,7 +366,8 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
||||
value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
|
||||
|
||||
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (UNEXPECTED(!make_real_object(&object))) {
|
||||
ZVAL_DEREF(object);
|
||||
if (UNEXPECTED(!make_real_object(object))) {
|
||||
zend_error(E_WARNING, "Attempt to assign property of non-object");
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
@ -377,7 +378,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
||||
|
||||
/* here we are sure we are dealing with an object */
|
||||
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
|
||||
|
||||
ZVAL_DEREF(zptr);
|
||||
SEPARATE_ZVAL_NOREF(zptr);
|
||||
@ -391,7 +392,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
||||
zval rv;
|
||||
|
||||
if (Z_OBJ_HT_P(object)->read_property &&
|
||||
(z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
|
||||
(z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) {
|
||||
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
|
||||
zval rv;
|
||||
zval *value = Z_OBJ_HT_P(z)->get(z, &rv);
|
||||
@ -404,7 +405,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
||||
ZVAL_DEREF(z);
|
||||
SEPARATE_ZVAL_NOREF(z);
|
||||
binary_op(z, z, value);
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL));
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), z);
|
||||
}
|
||||
@ -765,7 +766,8 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
|
||||
|
||||
do {
|
||||
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (UNEXPECTED(!make_real_object(&object))) {
|
||||
ZVAL_DEREF(object);
|
||||
if (UNEXPECTED(!make_real_object(object))) {
|
||||
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_NULL(retval);
|
||||
@ -777,7 +779,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
|
||||
/* here we are sure we are dealing with an object */
|
||||
|
||||
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
|
||||
|
||||
ZVAL_DEREF(zptr);
|
||||
SEPARATE_ZVAL_NOREF(zptr);
|
||||
@ -790,7 +792,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
|
||||
zval rv;
|
||||
|
||||
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
|
||||
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv);
|
||||
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
|
||||
zval rv;
|
||||
@ -807,7 +809,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(retval, z);
|
||||
}
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL));
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
|
||||
zval_ptr_dtor(z);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
|
||||
@ -854,7 +856,8 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
||||
|
||||
do {
|
||||
if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
|
||||
if (UNEXPECTED(!make_real_object(&object))) {
|
||||
ZVAL_DEREF(object);
|
||||
if (UNEXPECTED(!make_real_object(object))) {
|
||||
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
|
||||
ZVAL_NULL(retval);
|
||||
break;
|
||||
@ -864,7 +867,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
||||
/* here we are sure we are dealing with an object */
|
||||
|
||||
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
|
||||
|
||||
ZVAL_DEREF(zptr);
|
||||
ZVAL_COPY_VALUE(retval, zptr);
|
||||
@ -874,7 +877,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
||||
} else {
|
||||
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
|
||||
zval rv;
|
||||
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv);
|
||||
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv);
|
||||
zval z_copy;
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
|
||||
@ -890,7 +893,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
||||
ZVAL_DUP(&z_copy, z);
|
||||
incdec_op(&z_copy);
|
||||
if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL));
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL));
|
||||
zval_ptr_dtor(&z_copy);
|
||||
zval_ptr_dtor(z);
|
||||
} else {
|
||||
@ -1131,7 +1134,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
|
||||
if (OP1_TYPE == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) {
|
||||
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
|
||||
retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1);
|
||||
retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*));
|
||||
|
||||
/* check if static properties were destoyed */
|
||||
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
|
||||
@ -1438,9 +1441,9 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
||||
|
||||
if (OP2_TYPE == IS_CONST &&
|
||||
EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
|
||||
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
|
||||
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*));
|
||||
|
||||
if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
|
||||
if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
|
||||
retval = OBJ_PROP(zobj, prop_offset);
|
||||
if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
@ -1460,7 +1463,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_no_object):
|
||||
zend_error(E_NOTICE, "Trying to get property of non-object");
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
|
||||
retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
|
||||
|
||||
if (retval != EX_VAR(opline->result.var)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
@ -1489,7 +1492,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1513,7 +1516,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1553,9 +1556,9 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
|
||||
|
||||
if (OP2_TYPE == IS_CONST &&
|
||||
EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
|
||||
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
|
||||
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*));
|
||||
|
||||
if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
|
||||
if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
|
||||
retval = OBJ_PROP(zobj, prop_offset);
|
||||
if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
@ -1575,7 +1578,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object):
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
|
||||
retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
|
||||
retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
|
||||
|
||||
if (retval != EX_VAR(opline->result.var)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
@ -1609,7 +1612,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPV
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1635,7 +1638,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
@ -1696,7 +1699,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
|
||||
}
|
||||
zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, OP1_TYPE, property_name, OP2_TYPE, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL));
|
||||
zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, OP1_TYPE, property_name, OP2_TYPE, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL));
|
||||
FREE_OP2();
|
||||
FREE_OP1_VAR_PTR();
|
||||
/* assign_obj has two opcodes! */
|
||||
@ -1711,7 +1714,6 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|CV)
|
||||
zend_free_op free_op1;
|
||||
zval *object_ptr;
|
||||
zend_free_op free_op2, free_op_data1;
|
||||
zval rv;
|
||||
zval *value;
|
||||
zval *variable_ptr;
|
||||
zval *dim;
|
||||
@ -1726,12 +1728,20 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|CV)
|
||||
ZEND_VM_C_LABEL(try_assign_dim):
|
||||
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) {
|
||||
ZEND_VM_C_LABEL(try_assign_dim_array):
|
||||
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
zend_fetch_dimension_address_W(&rv, object_ptr, dim, OP2_TYPE);
|
||||
FREE_OP2();
|
||||
if (OP2_TYPE == IS_UNUSED) {
|
||||
SEPARATE_ARRAY(object_ptr);
|
||||
variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval));
|
||||
if (UNEXPECTED(variable_ptr == NULL)) {
|
||||
zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
|
||||
variable_ptr = &EG(error_zval);
|
||||
}
|
||||
} else {
|
||||
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
SEPARATE_ARRAY(object_ptr);
|
||||
variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, OP2_TYPE, BP_VAR_W);
|
||||
FREE_OP2();
|
||||
}
|
||||
value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
|
||||
ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
|
||||
variable_ptr = Z_INDIRECT(rv);
|
||||
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
|
||||
FREE_OP(free_op_data1);
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
@ -1752,21 +1762,41 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
|
||||
|
||||
zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data);
|
||||
FREE_OP2();
|
||||
} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
|
||||
EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
|
||||
zend_long offset;
|
||||
} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
|
||||
if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
|
||||
zend_long offset;
|
||||
|
||||
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W);
|
||||
FREE_OP2();
|
||||
value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
|
||||
zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
|
||||
FREE_OP(free_op_data1);
|
||||
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W);
|
||||
FREE_OP2();
|
||||
value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
|
||||
zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
|
||||
FREE_OP(free_op_data1);
|
||||
} else {
|
||||
zval_ptr_dtor_nogc(object_ptr);
|
||||
ZEND_VM_C_LABEL(assign_dim_convert_to_array):
|
||||
ZVAL_NEW_ARR(object_ptr);
|
||||
zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0);
|
||||
ZEND_VM_C_GOTO(try_assign_dim_array);
|
||||
}
|
||||
} else if (EXPECTED(Z_ISREF_P(object_ptr))) {
|
||||
object_ptr = Z_REFVAL_P(object_ptr);
|
||||
ZEND_VM_C_GOTO(try_assign_dim);
|
||||
} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
|
||||
if (UNEXPECTED(object_ptr == &EG(error_zval))) {
|
||||
ZEND_VM_C_GOTO(assign_dim_clean);
|
||||
}
|
||||
ZEND_VM_C_GOTO(assign_dim_convert_to_array);
|
||||
} else {
|
||||
ZEND_VM_C_GOTO(try_assign_dim_array);
|
||||
zend_error(E_WARNING, "Cannot use a scalar value as an array");
|
||||
ZEND_VM_C_LABEL(assign_dim_clean):
|
||||
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
FREE_OP2();
|
||||
value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
|
||||
FREE_OP(free_op_data1);
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
}
|
||||
}
|
||||
FREE_OP1_VAR_PTR();
|
||||
/* assign_dim has two opcodes! */
|
||||
@ -2347,13 +2377,17 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
|
||||
if (opline->opcode == ZEND_INIT_FCALL ||
|
||||
opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
|
||||
opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
|
||||
opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
|
||||
opline->opcode == ZEND_INIT_METHOD_CALL ||
|
||||
opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
|
||||
opline->opcode == ZEND_INIT_USER_CALL ||
|
||||
opline->opcode == ZEND_NEW
|
||||
) {
|
||||
nesting++;
|
||||
} else if (opline->opcode == ZEND_DO_FCALL) {
|
||||
} else if (opline->opcode == ZEND_DO_FCALL ||
|
||||
opline->opcode == ZEND_DO_ICALL ||
|
||||
opline->opcode == ZEND_DO_UCALL ||
|
||||
opline->opcode == ZEND_DO_FCALL_BY_NAME) {
|
||||
nesting--;
|
||||
}
|
||||
} while (nesting);
|
||||
@ -2534,150 +2568,154 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMPVAR|CV)
|
||||
ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_function *fbc;
|
||||
zval *function_name, *func;
|
||||
|
||||
if (OP2_TYPE == IS_CONST && Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_STRING) {
|
||||
if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) {
|
||||
fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
function_name = (zval*)(EX_CONSTANT(opline->op2)+1);
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
|
||||
if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
|
||||
SAVE_OPLINE();
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
fbc = Z_FUNC_P(func);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
|
||||
}
|
||||
}
|
||||
EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
|
||||
fbc, opline->extended_value, NULL, NULL, EX(call));
|
||||
|
||||
EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
|
||||
fbc, opline->extended_value, NULL, NULL, EX(call));
|
||||
/*CHECK_EXCEPTION();*/
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
/*CHECK_EXCEPTION();*/
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
zend_string *lcname;
|
||||
zend_free_op free_op2;
|
||||
zend_class_entry *called_scope;
|
||||
zend_object *object;
|
||||
ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_function *fbc;
|
||||
zval *function_name, *func;
|
||||
zend_string *lcname;
|
||||
zend_free_op free_op2;
|
||||
zend_class_entry *called_scope;
|
||||
zend_object *object;
|
||||
|
||||
SAVE_OPLINE();
|
||||
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
SAVE_OPLINE();
|
||||
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
ZEND_VM_C_LABEL(try_function_name):
|
||||
if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
|
||||
if (Z_STRVAL_P(function_name)[0] == '\\') {
|
||||
lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
|
||||
zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
|
||||
} else {
|
||||
lcname = zend_string_tolower(Z_STR_P(function_name));
|
||||
}
|
||||
if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
|
||||
}
|
||||
zend_string_release(lcname);
|
||||
if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
|
||||
if (Z_STRVAL_P(function_name)[0] == '\\') {
|
||||
lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0);
|
||||
zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1);
|
||||
} else {
|
||||
lcname = zend_string_tolower(Z_STR_P(function_name));
|
||||
}
|
||||
if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name));
|
||||
}
|
||||
zend_string_release(lcname);
|
||||
FREE_OP2();
|
||||
|
||||
fbc = Z_FUNC_P(func);
|
||||
called_scope = NULL;
|
||||
object = NULL;
|
||||
} else if (OP2_TYPE != IS_CONST &&
|
||||
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
|
||||
Z_OBJ_HANDLER_P(function_name, get_closure) &&
|
||||
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) {
|
||||
if (object) {
|
||||
GC_REFCOUNT(object)++;
|
||||
}
|
||||
if (OP2_TYPE == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
|
||||
/* Delay closure destruction until its invocation */
|
||||
fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
|
||||
} else if (OP2_TYPE == IS_CV) {
|
||||
FREE_OP2();
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
|
||||
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
|
||||
zval *obj;
|
||||
zval *method;
|
||||
obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
|
||||
method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
|
||||
|
||||
fbc = Z_FUNC_P(func);
|
||||
called_scope = NULL;
|
||||
if (!obj || !method) {
|
||||
zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
|
||||
}
|
||||
|
||||
ZVAL_DEREF(obj);
|
||||
if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
|
||||
zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
|
||||
}
|
||||
|
||||
ZVAL_DEREF(method);
|
||||
if (Z_TYPE_P(method) != IS_STRING) {
|
||||
zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(obj) == IS_STRING) {
|
||||
object = NULL;
|
||||
} else if (OP2_TYPE != IS_CONST &&
|
||||
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
|
||||
Z_OBJ_HANDLER_P(function_name, get_closure) &&
|
||||
Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) {
|
||||
if (object) {
|
||||
GC_REFCOUNT(object)++;
|
||||
}
|
||||
if (OP2_TYPE == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) {
|
||||
/* Delay closure destruction until its invocation */
|
||||
fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2);
|
||||
} else if (OP2_TYPE == IS_CV) {
|
||||
FREE_OP2();
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
|
||||
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
|
||||
zval *obj;
|
||||
zval *method;
|
||||
|
||||
obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0);
|
||||
method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1);
|
||||
|
||||
if (!obj || !method) {
|
||||
zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1");
|
||||
called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
|
||||
if (UNEXPECTED(called_scope == NULL)) {
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZVAL_DEREF(obj);
|
||||
if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) {
|
||||
zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object");
|
||||
if (called_scope->get_static_method) {
|
||||
fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
|
||||
} else {
|
||||
fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
|
||||
}
|
||||
|
||||
ZVAL_DEREF(method);
|
||||
if (Z_TYPE_P(method) != IS_STRING) {
|
||||
zend_error_noreturn(E_ERROR, "Second array member is not a valid method");
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(obj) == IS_STRING) {
|
||||
object = NULL;
|
||||
called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0);
|
||||
if (UNEXPECTED(called_scope == NULL)) {
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
if (called_scope->get_static_method) {
|
||||
fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
|
||||
} else {
|
||||
fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
|
||||
}
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method));
|
||||
}
|
||||
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
|
||||
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
|
||||
zend_error(E_STRICT,
|
||||
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
|
||||
if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
|
||||
zend_error(E_STRICT,
|
||||
"Non-static method %s::%s() should not be called statically",
|
||||
fbc->common.scope->name->val, fbc->common.function_name->val);
|
||||
} else {
|
||||
zend_error_noreturn(
|
||||
E_ERROR,
|
||||
"Non-static method %s::%s() cannot be called statically",
|
||||
fbc->common.scope->name->val, fbc->common.function_name->val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
called_scope = Z_OBJCE_P(obj);
|
||||
object = Z_OBJ_P(obj);
|
||||
|
||||
fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
|
||||
}
|
||||
|
||||
if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
|
||||
object = NULL;
|
||||
} else {
|
||||
GC_REFCOUNT(object)++; /* For $this pointer */
|
||||
zend_error_noreturn(
|
||||
E_ERROR,
|
||||
"Non-static method %s::%s() cannot be called statically",
|
||||
fbc->common.scope->name->val, fbc->common.function_name->val);
|
||||
}
|
||||
}
|
||||
FREE_OP2();
|
||||
} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
|
||||
function_name = Z_REFVAL_P(function_name);
|
||||
ZEND_VM_C_GOTO(try_function_name);
|
||||
} else {
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
zend_error_noreturn(E_ERROR, "Function name must be a string");
|
||||
ZEND_VM_CONTINUE(); /* Never reached */
|
||||
}
|
||||
EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
|
||||
fbc, opline->extended_value, called_scope, object, EX(call));
|
||||
called_scope = Z_OBJCE_P(obj);
|
||||
object = Z_OBJ_P(obj);
|
||||
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method));
|
||||
}
|
||||
|
||||
if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
|
||||
object = NULL;
|
||||
} else {
|
||||
GC_REFCOUNT(object)++; /* For $this pointer */
|
||||
}
|
||||
}
|
||||
FREE_OP2();
|
||||
} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
|
||||
function_name = Z_REFVAL_P(function_name);
|
||||
ZEND_VM_C_GOTO(try_function_name);
|
||||
} else {
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
zend_error_noreturn(E_ERROR, "Function name must be a string");
|
||||
ZEND_VM_CONTINUE(); /* Never reached */
|
||||
}
|
||||
EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
|
||||
fbc, opline->extended_value, called_scope, object, EX(call));
|
||||
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV)
|
||||
@ -2791,6 +2829,185 @@ ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
LOAD_OPLINE();
|
||||
|
||||
call->called_scope = EX(called_scope);
|
||||
Z_OBJ(call->This) = Z_OBJ(EX(This));
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
|
||||
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
}
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL);
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
}
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
LOAD_OPLINE();
|
||||
|
||||
EG(scope) = NULL;
|
||||
ret = NULL;
|
||||
call->symbol_table = NULL;
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
i_init_func_execute_data(call, &fbc->op_array, ret, 0);
|
||||
|
||||
ZEND_VM_ENTER();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
LOAD_OPLINE();
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
EG(scope) = NULL;
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var));
|
||||
} else {
|
||||
zend_vm_stack_free_args(call);
|
||||
}
|
||||
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
} else {
|
||||
ret = NULL;
|
||||
call->symbol_table = NULL;
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = 0;
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
i_init_func_execute_data(call, &fbc->op_array, ret, 0);
|
||||
|
||||
ZEND_VM_ENTER();
|
||||
}
|
||||
EG(scope) = EX(func)->op_array.scope;
|
||||
} else {
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
|
||||
fbc->common.scope ? fbc->common.scope->name->val : "",
|
||||
fbc->common.scope ? "::" : "",
|
||||
fbc->common.function_name->val);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
|
||||
call->called_scope = EX(called_scope);
|
||||
Z_OBJ(call->This) = Z_OBJ(EX(This));
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
|
||||
uint32_t i;
|
||||
uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
|
||||
zval *p = ZEND_CALL_ARG(call, 1);
|
||||
|
||||
for (i = 0; i < num_args; ++i) {
|
||||
zend_verify_internal_arg_type(fbc, i + 1, p);
|
||||
p++;
|
||||
}
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
zend_throw_exception_internal(NULL);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
|
||||
ret = EX_VAR(opline->result.var);
|
||||
ZVAL_NULL(ret);
|
||||
Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
|
||||
|
||||
fbc->internal_function.handler(call, ret);
|
||||
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
|
||||
EG(current_execute_data) = call->prev_execute_data;
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
}
|
||||
}
|
||||
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
zend_throw_exception_internal(NULL);
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(EX_VAR(opline->result.var));
|
||||
}
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -2838,7 +3055,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
i_init_func_execute_data(call, &fbc->op_array, ret);
|
||||
i_init_func_execute_data(call, &fbc->op_array, ret, 1);
|
||||
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
ZEND_VM_ENTER();
|
||||
@ -2849,7 +3066,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
|
||||
}
|
||||
} else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
|
||||
int should_change_scope = 0;
|
||||
zval *ret;
|
||||
|
||||
if (fbc->common.scope) {
|
||||
should_change_scope = 1;
|
||||
@ -4654,7 +4870,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
||||
}
|
||||
}
|
||||
if (Z_OBJ_HT_P(container)->unset_property) {
|
||||
Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL));
|
||||
Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
|
||||
} else {
|
||||
zend_error(E_NOTICE, "Trying to unset property of non-object");
|
||||
}
|
||||
@ -5316,7 +5532,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
|
||||
if (OP1_TYPE == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) {
|
||||
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
|
||||
value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1);
|
||||
value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*));
|
||||
|
||||
/* check if static properties were destoyed */
|
||||
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
|
||||
@ -5523,7 +5739,7 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|
|
||||
ZEND_VM_C_LABEL(isset_no_object):
|
||||
result = ((opline->extended_value & ZEND_ISSET) == 0);
|
||||
} else {
|
||||
result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL));
|
||||
result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
|
||||
if ((opline->extended_value & ZEND_ISSET) == 0) {
|
||||
result = !result;
|
||||
}
|
||||
@ -5960,11 +6176,15 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
do {
|
||||
switch (opline->opcode) {
|
||||
case ZEND_DO_FCALL:
|
||||
case ZEND_DO_ICALL:
|
||||
case ZEND_DO_UCALL:
|
||||
case ZEND_DO_FCALL_BY_NAME:
|
||||
level++;
|
||||
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_INIT_USER_CALL:
|
||||
case ZEND_INIT_METHOD_CALL:
|
||||
case ZEND_INIT_STATIC_METHOD_CALL:
|
||||
@ -6005,11 +6225,15 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
do {
|
||||
switch (opline->opcode) {
|
||||
case ZEND_DO_FCALL:
|
||||
case ZEND_DO_ICALL:
|
||||
case ZEND_DO_UCALL:
|
||||
case ZEND_DO_FCALL_BY_NAME:
|
||||
level++;
|
||||
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_INIT_USER_CALL:
|
||||
case ZEND_INIT_METHOD_CALL:
|
||||
case ZEND_INIT_STATIC_METHOD_CALL:
|
||||
@ -6609,7 +6833,7 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(128, ZEND_ASSERT_CHECK, ANY, ANY)
|
||||
ZEND_VM_HANDLER(137, ZEND_ASSERT_CHECK, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -967,7 +967,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
|
||||
out($f,"#undef LOAD_OPLINE\n");
|
||||
out($f,"#undef SAVE_OPLINE\n");
|
||||
out($f,"#define OPLINE opline\n");
|
||||
out($f,"#define DCL_OPLINE zend_op *opline;\n");
|
||||
out($f,"#define DCL_OPLINE const zend_op *opline;\n");
|
||||
out($f,"#define USE_OPLINE\n");
|
||||
out($f,"#define LOAD_OPLINE() opline = EX(opline)\n");
|
||||
out($f,"#define SAVE_OPLINE() EX(opline) = opline\n");
|
||||
@ -993,7 +993,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
|
||||
out($f,"#undef LOAD_OPLINE\n");
|
||||
out($f,"#undef SAVE_OPLINE\n");
|
||||
out($f,"#define OPLINE opline\n");
|
||||
out($f,"#define DCL_OPLINE zend_op *opline;\n");
|
||||
out($f,"#define DCL_OPLINE const zend_op *opline;\n");
|
||||
out($f,"#define USE_OPLINE\n");
|
||||
out($f,"#define LOAD_OPLINE() opline = EX(opline)\n");
|
||||
out($f,"#define SAVE_OPLINE() EX(opline) = opline\n");
|
||||
|
@ -150,16 +150,16 @@ const char *zend_vm_opcodes_map[171] = {
|
||||
"ZEND_FE_RESET_RW",
|
||||
"ZEND_FE_FETCH_RW",
|
||||
"ZEND_FE_FREE",
|
||||
"ZEND_ASSERT_CHECK",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"ZEND_INIT_DYNAMIC_CALL",
|
||||
"ZEND_DO_ICALL",
|
||||
"ZEND_DO_UCALL",
|
||||
"ZEND_DO_FCALL_BY_NAME",
|
||||
"ZEND_PRE_INC_OBJ",
|
||||
"ZEND_PRE_DEC_OBJ",
|
||||
"ZEND_POST_INC_OBJ",
|
||||
"ZEND_POST_DEC_OBJ",
|
||||
"ZEND_ASSIGN_OBJ",
|
||||
NULL,
|
||||
"ZEND_ASSERT_CHECK",
|
||||
"ZEND_INSTANCEOF",
|
||||
"ZEND_DECLARE_CLASS",
|
||||
"ZEND_DECLARE_INHERITED_CLASS",
|
||||
|
@ -152,12 +152,16 @@ END_EXTERN_C()
|
||||
#define ZEND_FE_RESET_RW 125
|
||||
#define ZEND_FE_FETCH_RW 126
|
||||
#define ZEND_FE_FREE 127
|
||||
#define ZEND_ASSERT_CHECK 128
|
||||
#define ZEND_INIT_DYNAMIC_CALL 128
|
||||
#define ZEND_DO_ICALL 129
|
||||
#define ZEND_DO_UCALL 130
|
||||
#define ZEND_DO_FCALL_BY_NAME 131
|
||||
#define ZEND_PRE_INC_OBJ 132
|
||||
#define ZEND_PRE_DEC_OBJ 133
|
||||
#define ZEND_POST_INC_OBJ 134
|
||||
#define ZEND_POST_DEC_OBJ 135
|
||||
#define ZEND_ASSIGN_OBJ 136
|
||||
#define ZEND_ASSERT_CHECK 137
|
||||
#define ZEND_INSTANCEOF 138
|
||||
#define ZEND_DECLARE_CLASS 139
|
||||
#define ZEND_DECLARE_INHERITED_CLASS 140
|
||||
|
@ -844,6 +844,11 @@ PHP_MINIT_FUNCTION(curl)
|
||||
REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4);
|
||||
REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5);
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x071200 /* Available since 7.18.0 */
|
||||
REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4A);
|
||||
REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5_HOSTNAME);
|
||||
#endif
|
||||
|
||||
/* Curl Share constants */
|
||||
REGISTER_CURL_CONSTANT(CURLSHOPT_NONE);
|
||||
REGISTER_CURL_CONSTANT(CURLSHOPT_SHARE);
|
||||
@ -1239,7 +1244,7 @@ PHP_MINIT_FUNCTION(curl)
|
||||
gcry_control(GCRYCTL_SET_THREAD_CBS, &php_curl_gnutls_tsl);
|
||||
#endif
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_SSL) != CURLE_OK) {
|
||||
if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
@ -809,6 +809,16 @@ PHP_RSHUTDOWN_FUNCTION(date)
|
||||
|
||||
#define DATE_FORMAT_ISO8601 "Y-m-d\\TH:i:sO"
|
||||
|
||||
/*
|
||||
* RFC3339, Appendix A: http://www.ietf.org/rfc/rfc3339.txt
|
||||
* ISO 8601 also requires (in section 5.3.1.3) that a decimal fraction
|
||||
* be proceeded by a "0" if less than unity. Annex B.2 of ISO 8601
|
||||
* gives examples where the decimal fractions are not preceded by a "0".
|
||||
* This grammar assumes section 5.3.1.3 is correct and that Annex B.2 is
|
||||
* in error.
|
||||
*/
|
||||
#define DATE_FORMAT_RFC3339_EXTENDED "Y-m-d\\TH:i:s.vP"
|
||||
|
||||
/*
|
||||
* This comes from various sources that like to contradict. I'm going with the
|
||||
* format here because of:
|
||||
@ -849,12 +859,15 @@ PHP_MINIT_FUNCTION(date)
|
||||
*/
|
||||
REGISTER_STRING_CONSTANT("DATE_COOKIE", DATE_FORMAT_COOKIE, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_STRING_CONSTANT("DATE_ISO8601", DATE_FORMAT_ISO8601, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
REGISTER_STRING_CONSTANT("DATE_RFC822", DATE_FORMAT_RFC822, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_STRING_CONSTANT("DATE_RFC850", DATE_FORMAT_RFC850, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_STRING_CONSTANT("DATE_RFC1036", DATE_FORMAT_RFC1036, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_STRING_CONSTANT("DATE_RFC1123", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_STRING_CONSTANT("DATE_RFC2822", DATE_FORMAT_RFC2822, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_STRING_CONSTANT("DATE_RFC3339_EXTENDED", DATE_FORMAT_RFC3339_EXTENDED, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
/*
|
||||
* RSS 2.0 Specification: http://blogs.law.harvard.edu/tech/rss
|
||||
* "All date-times in RSS conform to the Date and Time Specification of RFC 822,
|
||||
@ -1145,6 +1158,7 @@ static zend_string *date_format(char *format, size_t format_len, timelib_time *t
|
||||
case 'i': length = slprintf(buffer, 32, "%02d", (int) t->i); break;
|
||||
case 's': length = slprintf(buffer, 32, "%02d", (int) t->s); break;
|
||||
case 'u': length = slprintf(buffer, 32, "%06d", (int) floor(t->f * 1000000 + 0.5)); break;
|
||||
case 'v': length = slprintf(buffer, 32, "%03d", (int) floor(t->f * 1000 + 0.5)); break;
|
||||
|
||||
/* timezone */
|
||||
case 'I': length = slprintf(buffer, 32, "%d", localtime ? offset->is_dst : 0); break;
|
||||
@ -1981,17 +1995,18 @@ static void date_register_classes(void) /* {{{ */
|
||||
#define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \
|
||||
zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1);
|
||||
|
||||
REGISTER_DATE_CLASS_CONST_STRING("ATOM", DATE_FORMAT_RFC3339);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("COOKIE", DATE_FORMAT_COOKIE);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("ISO8601", DATE_FORMAT_ISO8601);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC822", DATE_FORMAT_RFC822);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC850", DATE_FORMAT_RFC850);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC1036", DATE_FORMAT_RFC1036);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC1123", DATE_FORMAT_RFC1123);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC2822", DATE_FORMAT_RFC2822);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC3339", DATE_FORMAT_RFC3339);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RSS", DATE_FORMAT_RFC1123);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("W3C", DATE_FORMAT_RFC3339);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("ATOM", DATE_FORMAT_RFC3339);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("COOKIE", DATE_FORMAT_COOKIE);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("ISO8601", DATE_FORMAT_ISO8601);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC822", DATE_FORMAT_RFC822);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC850", DATE_FORMAT_RFC850);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC1036", DATE_FORMAT_RFC1036);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC1123", DATE_FORMAT_RFC1123);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC2822", DATE_FORMAT_RFC2822);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC3339", DATE_FORMAT_RFC3339);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RFC3339_EXTENDED", DATE_FORMAT_RFC3339_EXTENDED);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("RSS", DATE_FORMAT_RFC1123);
|
||||
REGISTER_DATE_CLASS_CONST_STRING("W3C", DATE_FORMAT_RFC3339);
|
||||
|
||||
INIT_CLASS_ENTRY(ce_immutable, "DateTimeImmutable", date_funcs_immutable);
|
||||
ce_immutable.create_object = date_object_new_date;
|
||||
|
@ -156,7 +156,7 @@ array(18) {
|
||||
}
|
||||
}
|
||||
..and get names of all its class constants
|
||||
array(11) {
|
||||
array(12) {
|
||||
["ATOM"]=>
|
||||
string(13) "Y-m-d\TH:i:sP"
|
||||
["COOKIE"]=>
|
||||
@ -175,6 +175,8 @@ array(11) {
|
||||
string(16) "D, d M Y H:i:s O"
|
||||
["RFC3339"]=>
|
||||
string(13) "Y-m-d\TH:i:sP"
|
||||
["RFC3339_EXTENDED"]=>
|
||||
string(15) "Y-m-d\TH:i:s.vP"
|
||||
["RSS"]=>
|
||||
string(16) "D, d M Y H:i:s O"
|
||||
["W3C"]=>
|
||||
|
17
ext/date/tests/bug69089.phpt
Normal file
17
ext/date/tests/bug69089.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Bug #69089 (Add support for RFC3339 extended to DateTime::format)
|
||||
--CREDITS--
|
||||
Mariano Iglesias <mariano@cricava.com>
|
||||
--FILE--
|
||||
<?php
|
||||
date_default_timezone_set('America/Buenos_Aires');
|
||||
|
||||
$date = new DateTime('2009-09-28 09:45:31.918312');
|
||||
|
||||
var_dump($date->format(DateTime::RFC3339_EXTENDED));
|
||||
var_dump($date->format('u'));
|
||||
var_dump($date->format('v'));
|
||||
--EXPECT--
|
||||
string(29) "2009-09-28T09:45:31.918-03:00"
|
||||
string(6) "918312"
|
||||
string(3) "918"
|
@ -1,11 +1,11 @@
|
||||
PHP_ARG_WITH(interbase,for InterBase support,
|
||||
[ --with-interbase[=DIR] Include InterBase support. DIR is the InterBase base
|
||||
install directory [/usr/interbase]])
|
||||
PHP_ARG_WITH(interbase,for Firebird support,
|
||||
[ --with-interbase[=DIR] Include Firebird support. DIR is the Firebird base
|
||||
install directory [/opt/firebird]])
|
||||
|
||||
if test "$PHP_INTERBASE" != "no"; then
|
||||
if test "$PHP_INTERBASE" = "yes"; then
|
||||
IBASE_INCDIR=/usr/interbase/include
|
||||
IBASE_LIBDIR=/usr/interbase/lib
|
||||
IBASE_INCDIR=/opt/firebird/include
|
||||
IBASE_LIBDIR=/opt/firebird/lib
|
||||
else
|
||||
IBASE_INCDIR=$PHP_INTERBASE/include
|
||||
IBASE_LIBDIR=$PHP_INTERBASE/$PHP_LIBDIR
|
||||
@ -23,7 +23,7 @@ if test "$PHP_INTERBASE" != "no"; then
|
||||
[
|
||||
IBASE_LIBNAME=ib_util
|
||||
], [
|
||||
AC_MSG_ERROR([libgds, libib_util or libfbclient not found! Check config.log for more information.])
|
||||
AC_MSG_ERROR([libfbclient, libgds or libib_util not found! Check config.log for more information.])
|
||||
], [
|
||||
-L$IBASE_LIBDIR
|
||||
])
|
||||
|
@ -94,23 +94,24 @@ static inline void php_json_pretty_print_indent(smart_str *buf, int options) /*
|
||||
|
||||
/* }}} */
|
||||
|
||||
static inline int php_json_is_valid_double(double d) /* {{{ */
|
||||
{
|
||||
return !zend_isinf(d) && !zend_isnan(d);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static inline void php_json_encode_double(smart_str *buf, double d, int options) /* {{{ */
|
||||
{
|
||||
if (!zend_isinf(d) && !zend_isnan(d)) {
|
||||
size_t len;
|
||||
char num[PHP_JSON_DOUBLE_MAX_LENGTH];
|
||||
php_gcvt(d, EG(precision), '.', 'e', &num[0]);
|
||||
len = strlen(num);
|
||||
if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_JSON_DOUBLE_MAX_LENGTH - 2) {
|
||||
num[len++] = '.';
|
||||
num[len++] = '0';
|
||||
num[len] = '\0';
|
||||
}
|
||||
smart_str_appendl(buf, num, len);
|
||||
} else {
|
||||
JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;
|
||||
smart_str_appendc(buf, '0');
|
||||
size_t len;
|
||||
char num[PHP_JSON_DOUBLE_MAX_LENGTH];
|
||||
php_gcvt(d, EG(precision), '.', 'e', &num[0]);
|
||||
len = strlen(num);
|
||||
if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_JSON_DOUBLE_MAX_LENGTH - 2) {
|
||||
num[len++] = '.';
|
||||
num[len++] = '0';
|
||||
num[len] = '\0';
|
||||
}
|
||||
smart_str_appendl(buf, num, len);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -293,10 +294,11 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti
|
||||
if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
|
||||
if (type == IS_LONG) {
|
||||
smart_str_append_long(buf, p);
|
||||
} else if (type == IS_DOUBLE) {
|
||||
return;
|
||||
} else if (type == IS_DOUBLE && php_json_is_valid_double(d)) {
|
||||
php_json_encode_double(buf, d, options);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
@ -506,7 +508,12 @@ again:
|
||||
break;
|
||||
|
||||
case IS_DOUBLE:
|
||||
php_json_encode_double(buf, Z_DVAL_P(val), options);
|
||||
if (php_json_is_valid_double(Z_DVAL_P(val))) {
|
||||
php_json_encode_double(buf, Z_DVAL_P(val), options);
|
||||
} else {
|
||||
JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;
|
||||
smart_str_appendc(buf, '0');
|
||||
}
|
||||
break;
|
||||
|
||||
case IS_STRING:
|
||||
|
14
ext/json/tests/bug64695.phpt
Normal file
14
ext/json/tests/bug64695.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug #64695 JSON_NUMERIC_CHECK has issues with strings that are numbers plus the letter e
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("json")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$t = array('test' => '123343e871700');
|
||||
var_dump(json_encode($t, JSON_NUMERIC_CHECK));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
string(24) "{"test":"123343e871700"}"
|
||||
Done
|
@ -9,4 +9,4 @@ declare(encoding="ISO-8859-1");
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
ok
|
||||
ok
|
@ -10,4 +10,4 @@ declare(encoding="ISO-8859-15") {
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
ok
|
||||
Fatal error: Encoding declaration pragma must be the very first statement in the script in %s on line %d
|
16
ext/mbstring/tests/zend_multibyte-15.phpt
Normal file
16
ext/mbstring/tests/zend_multibyte-15.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
zend multibyte (15)
|
||||
--INI--
|
||||
zend.multibyte=1
|
||||
--FILE--
|
||||
<?php
|
||||
declare(encoding="ISO-8859-15") {
|
||||
echo "ok\n";
|
||||
}
|
||||
declare(encoding="UTF-8") {
|
||||
echo "ok\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
ok
|
||||
ok
|
14
ext/mbstring/tests/zend_multibyte-16.phpt
Normal file
14
ext/mbstring/tests/zend_multibyte-16.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
zend multibyte (16)
|
||||
--INI--
|
||||
zend.multibyte=1
|
||||
--FILE--
|
||||
<?php
|
||||
declare(encoding="ISO-8859-15") {
|
||||
echo "ok\n";
|
||||
}
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
ok
|
||||
ok
|
@ -1830,6 +1830,9 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char *
|
||||
case ZEND_ASSIGN:
|
||||
case ZEND_ASSIGN_REF:
|
||||
case ZEND_DO_FCALL:
|
||||
case ZEND_DO_ICALL:
|
||||
case ZEND_DO_UCALL:
|
||||
case ZEND_DO_FCALL_BY_NAME:
|
||||
if (ZEND_RESULT_TYPE(opline) == IS_VAR) {
|
||||
ZEND_RESULT_TYPE(opline) |= EXT_TYPE_UNUSED;
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ static void optimizer_literal_class_info(literal_info *info,
|
||||
void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
{
|
||||
zend_op *opline, *end;
|
||||
int i, j, n, *map, cache_slots;
|
||||
int i, j, n, *map, cache_size;
|
||||
zval zv, *pos;
|
||||
literal_info *info;
|
||||
int l_null = -1;
|
||||
@ -139,9 +139,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
||||
LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 1);
|
||||
break;
|
||||
case ZEND_INIT_FCALL_BY_NAME:
|
||||
if (ZEND_OP2_TYPE(opline) == IS_CONST) {
|
||||
LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 2);
|
||||
}
|
||||
LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 2);
|
||||
break;
|
||||
case ZEND_INIT_NS_FCALL_BY_NAME:
|
||||
LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 3);
|
||||
@ -320,7 +318,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
||||
#endif
|
||||
|
||||
/* Merge equal constants */
|
||||
j = 0; cache_slots = 0;
|
||||
j = 0; cache_size = 0;
|
||||
zend_hash_init(&hash, op_array->last_literal, NULL, NULL, 0);
|
||||
map = (int*)zend_arena_alloc(&ctx->arena, op_array->last_literal * sizeof(int));
|
||||
memset(map, 0, op_array->last_literal * sizeof(int));
|
||||
@ -441,8 +439,8 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
||||
info[j] = info[i];
|
||||
}
|
||||
if (LITERAL_NUM_SLOTS(info[i].flags)) {
|
||||
Z_CACHE_SLOT(op_array->literals[j]) = cache_slots;
|
||||
cache_slots += LITERAL_NUM_SLOTS(info[i].flags);
|
||||
Z_CACHE_SLOT(op_array->literals[j]) = cache_size;
|
||||
cache_size += LITERAL_NUM_SLOTS(info[i].flags) * sizeof(void*);
|
||||
}
|
||||
j++;
|
||||
n = LITERAL_NUM_RELATED(info[i].flags);
|
||||
@ -467,7 +465,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
||||
}
|
||||
zend_hash_destroy(&hash);
|
||||
op_array->last_literal = j;
|
||||
op_array->last_cache_slot = cache_slots;
|
||||
op_array->cache_size = cache_size;
|
||||
|
||||
/* Update opcodes to use new literals table */
|
||||
opline = op_array->opcodes;
|
||||
|
@ -66,6 +66,7 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
}
|
||||
/* break missing intentionally */
|
||||
case ZEND_NEW:
|
||||
case ZEND_INIT_DYNAMIC_CALL:
|
||||
case ZEND_INIT_METHOD_CALL:
|
||||
case ZEND_INIT_STATIC_METHOD_CALL:
|
||||
case ZEND_INIT_FCALL:
|
||||
@ -74,6 +75,9 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
call++;
|
||||
break;
|
||||
case ZEND_DO_FCALL:
|
||||
case ZEND_DO_ICALL:
|
||||
case ZEND_DO_UCALL:
|
||||
case ZEND_DO_FCALL_BY_NAME:
|
||||
call--;
|
||||
if (call_stack[call].func && call_stack[call].opline) {
|
||||
zend_op *fcall = call_stack[call].opline;
|
||||
@ -84,6 +88,7 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]);
|
||||
literal_dtor(&ZEND_OP2_LITERAL(fcall));
|
||||
fcall->op2.constant = fcall->op2.constant + 1;
|
||||
opline->opcode = zend_get_call_op(ZEND_INIT_FCALL, call_stack[call].func);
|
||||
} else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
|
||||
fcall->opcode = ZEND_INIT_FCALL;
|
||||
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
|
||||
@ -91,6 +96,7 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
literal_dtor(&op_array->literals[fcall->op2.constant]);
|
||||
literal_dtor(&op_array->literals[fcall->op2.constant + 2]);
|
||||
fcall->op2.constant = fcall->op2.constant + 1;
|
||||
opline->opcode = zend_get_call_op(ZEND_INIT_FCALL, call_stack[call].func);
|
||||
} else {
|
||||
ZEND_ASSERT(0);
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
}
|
||||
break;
|
||||
|
||||
case ZEND_DO_FCALL: {
|
||||
case ZEND_DO_ICALL: {
|
||||
zend_op *send1_opline = opline - 1;
|
||||
zend_op *send2_opline = NULL;
|
||||
zend_op *init_opline = NULL;
|
||||
|
@ -129,7 +129,8 @@ void zend_optimizer_update_op1_const(zend_op_array *op_array,
|
||||
case ZEND_NEW:
|
||||
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->last_cache_slot++;
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size;
|
||||
op_array->cache_size += sizeof(void*);
|
||||
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
|
||||
zend_optimizer_add_literal(op_array, val);
|
||||
zend_string_hash_val(Z_STR(op_array->literals[opline->op1.constant+1]));
|
||||
@ -154,7 +155,8 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
|
||||
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
|
||||
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
|
||||
zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline)));
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++;
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
|
||||
op_array->cache_size += sizeof(void*);
|
||||
return;
|
||||
}
|
||||
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
|
||||
@ -175,7 +177,16 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
|
||||
case ZEND_ADD_INTERFACE:
|
||||
case ZEND_ADD_TRAIT:
|
||||
case ZEND_INSTANCEOF:
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++;
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
|
||||
op_array->cache_size += sizeof(void*);
|
||||
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
|
||||
zend_optimizer_add_literal(op_array, val);
|
||||
zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
|
||||
break;
|
||||
case ZEND_INIT_DYNAMIC_CALL:
|
||||
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
|
||||
op_array->cache_size += sizeof(void*);
|
||||
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
|
||||
zend_optimizer_add_literal(op_array, val);
|
||||
zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1]));
|
||||
@ -200,8 +211,8 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
|
||||
case ZEND_POST_INC_OBJ:
|
||||
case ZEND_POST_DEC_OBJ:
|
||||
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot;
|
||||
op_array->last_cache_slot += 2;
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
|
||||
op_array->cache_size += 2 * sizeof(void*);
|
||||
break;
|
||||
case ZEND_ASSIGN_ADD:
|
||||
case ZEND_ASSIGN_SUB:
|
||||
@ -215,8 +226,8 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
|
||||
case ZEND_ASSIGN_BW_AND:
|
||||
case ZEND_ASSIGN_BW_XOR:
|
||||
if (opline->extended_value == ZEND_ASSIGN_OBJ) {
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot;
|
||||
op_array->last_cache_slot += 2;
|
||||
Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size;
|
||||
op_array->cache_size += 2 * sizeof(void*);
|
||||
}
|
||||
break;
|
||||
case ZEND_OP_DATA:
|
||||
@ -309,15 +320,26 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
|
||||
* and allows its reuse. The number of ZEND_CASE instructions
|
||||
* usually terminated by ZEND_FREE that finally kills the value.
|
||||
*/
|
||||
case ZEND_FREE:
|
||||
case ZEND_CASE: {
|
||||
zend_op *m, *n;
|
||||
int brk = op_array->last_brk_cont;
|
||||
zend_bool in_switch = 0;
|
||||
while (brk--) {
|
||||
if (op_array->brk_cont_array[brk].start <= (opline - op_array->opcodes) &&
|
||||
op_array->brk_cont_array[brk].brk > (opline - op_array->opcodes)) {
|
||||
in_switch = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_switch) {
|
||||
ZEND_ASSERT(opline->opcode == ZEND_FREE);
|
||||
MAKE_NOP(opline);
|
||||
zval_dtor(val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
m = opline;
|
||||
n = op_array->opcodes + op_array->brk_cont_array[brk].brk + 1;
|
||||
while (m < n) {
|
||||
@ -340,10 +362,6 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
|
||||
zval_dtor(val);
|
||||
return 1;
|
||||
}
|
||||
case ZEND_FREE:
|
||||
MAKE_NOP(opline);
|
||||
zval_dtor(val);
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1163,7 +1163,13 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
|
||||
memory_used = zend_accel_script_persist_calc(new_persistent_script, key, key_length);
|
||||
|
||||
/* Allocate shared memory */
|
||||
#ifdef __SSE2__
|
||||
/* Align to 64-byte boundary */
|
||||
ZCG(mem) = zend_shared_alloc(memory_used + 64);
|
||||
ZCG(mem) = (void*)(((zend_uintptr_t)ZCG(mem) + 63L) & ~63L);
|
||||
#else
|
||||
ZCG(mem) = zend_shared_alloc(memory_used);
|
||||
#endif
|
||||
if (!ZCG(mem)) {
|
||||
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM);
|
||||
zend_shared_alloc_unlock();
|
||||
@ -1830,6 +1836,11 @@ static void accel_activate(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ZCG(function_table).nTableSize) {
|
||||
zend_hash_init(&ZCG(function_table), zend_hash_num_elements(CG(function_table)), NULL, ZEND_FUNCTION_DTOR, 1);
|
||||
zend_accel_copy_internal_functions();
|
||||
}
|
||||
|
||||
SHM_UNPROTECT();
|
||||
/* PHP-5.4 and above return "double", but we use 1 sec precision */
|
||||
ZCG(auto_globals_mask) = 0;
|
||||
@ -1973,7 +1984,11 @@ static int accel_clean_non_persistent_function(zval *zv)
|
||||
return ZEND_HASH_APPLY_STOP;
|
||||
} else {
|
||||
if (function->op_array.static_variables) {
|
||||
accel_fast_hash_destroy(function->op_array.static_variables);
|
||||
if (!(GC_FLAGS(function->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
if (--GC_REFCOUNT(function->op_array.static_variables) == 0) {
|
||||
accel_fast_hash_destroy(function->op_array.static_variables);
|
||||
}
|
||||
}
|
||||
function->op_array.static_variables = NULL;
|
||||
}
|
||||
return ZEND_HASH_APPLY_REMOVE;
|
||||
@ -2025,7 +2040,11 @@ static void zend_accel_fast_shutdown(void)
|
||||
break;
|
||||
} else {
|
||||
if (func->op_array.static_variables) {
|
||||
accel_fast_hash_destroy(func->op_array.static_variables);
|
||||
if (!(GC_FLAGS(func->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
if (--GC_REFCOUNT(func->op_array.static_variables) == 0) {
|
||||
accel_fast_hash_destroy(func->op_array.static_variables);
|
||||
}
|
||||
}
|
||||
}
|
||||
zend_accel_fast_del_bucket(EG(function_table), _idx-1, _p);
|
||||
}
|
||||
@ -2043,7 +2062,11 @@ static void zend_accel_fast_shutdown(void)
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
|
||||
if (func->type == ZEND_USER_FUNCTION) {
|
||||
if (func->op_array.static_variables) {
|
||||
accel_fast_hash_destroy(func->op_array.static_variables);
|
||||
if (!(GC_FLAGS(func->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
if (--GC_REFCOUNT(func->op_array.static_variables) == 0) {
|
||||
accel_fast_hash_destroy(func->op_array.static_variables);
|
||||
}
|
||||
}
|
||||
func->op_array.static_variables = NULL;
|
||||
}
|
||||
}
|
||||
@ -2239,8 +2262,6 @@ static void accel_globals_ctor(zend_accel_globals *accel_globals)
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
#endif
|
||||
memset(accel_globals, 0, sizeof(zend_accel_globals));
|
||||
zend_hash_init(&accel_globals->function_table, zend_hash_num_elements(CG(function_table)), NULL, ZEND_FUNCTION_DTOR, 1);
|
||||
zend_accel_copy_internal_functions();
|
||||
}
|
||||
|
||||
static void accel_globals_internal_func_dtor(zval *zv)
|
||||
@ -2250,8 +2271,10 @@ static void accel_globals_internal_func_dtor(zval *zv)
|
||||
|
||||
static void accel_globals_dtor(zend_accel_globals *accel_globals)
|
||||
{
|
||||
accel_globals->function_table.pDestructor = accel_globals_internal_func_dtor;
|
||||
zend_hash_destroy(&accel_globals->function_table);
|
||||
if (accel_globals->function_table.nTableSize) {
|
||||
accel_globals->function_table.pDestructor = accel_globals_internal_func_dtor;
|
||||
zend_hash_destroy(&accel_globals->function_table);
|
||||
}
|
||||
}
|
||||
|
||||
static int accel_startup(zend_extension *extension)
|
||||
@ -2404,11 +2427,6 @@ static int accel_startup(zend_extension *extension)
|
||||
zend_accel_blacklist_load(&accel_blacklist, ZCG(accel_directives.user_blacklist_filename));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* FIXME: We probably don't need it here */
|
||||
zend_accel_copy_internal_functions();
|
||||
#endif
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -49,8 +49,17 @@ function c($b = "bad") {
|
||||
}
|
||||
var_dump(c());
|
||||
|
||||
function d() {
|
||||
switch (PHP_OS) {
|
||||
default: return "bad";
|
||||
case PHP_OS: return "okey";
|
||||
}
|
||||
}
|
||||
|
||||
var_dump(d());
|
||||
?>
|
||||
--EXPECT--
|
||||
string(4) "okey"
|
||||
string(4) "okey"
|
||||
string(4) "okey"
|
||||
string(4) "okey"
|
||||
|
@ -25,10 +25,6 @@
|
||||
#include "zend_persist.h"
|
||||
#include "zend_shared_alloc.h"
|
||||
|
||||
#define ZEND_PROTECTED_REFCOUNT (1<<30)
|
||||
|
||||
static uint32_t zend_accel_refcount = ZEND_PROTECTED_REFCOUNT;
|
||||
|
||||
#if SIZEOF_SIZE_T <= SIZEOF_ZEND_LONG
|
||||
/* If sizeof(void*) == sizeof(ulong) we can use zend_hash index functions */
|
||||
# define accel_xlat_set(old, new) zend_hash_index_update_ptr(&ZCG(bind_hash), (zend_ulong)(zend_uintptr_t)(old), (new))
|
||||
@ -55,8 +51,11 @@ static void zend_accel_destroy_zend_function(zval *zv)
|
||||
|
||||
if (function->type == ZEND_USER_FUNCTION) {
|
||||
if (function->op_array.static_variables) {
|
||||
|
||||
FREE_HASHTABLE(function->op_array.static_variables);
|
||||
if (!(GC_FLAGS(function->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
if (--GC_REFCOUNT(function->op_array.static_variables) == 0) {
|
||||
FREE_HASHTABLE(function->op_array.static_variables);
|
||||
}
|
||||
}
|
||||
function->op_array.static_variables = NULL;
|
||||
}
|
||||
}
|
||||
@ -366,31 +365,11 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind)
|
||||
}
|
||||
}
|
||||
|
||||
/* protects reference count, creates copy of statics */
|
||||
static zend_always_inline void zend_prepare_function_for_execution(zend_op_array *op_array)
|
||||
{
|
||||
/* protect reference count */
|
||||
op_array->refcount = &zend_accel_refcount;
|
||||
(*op_array->refcount) = ZEND_PROTECTED_REFCOUNT;
|
||||
|
||||
/* copy statics */
|
||||
if (UNEXPECTED(op_array->static_variables)) {
|
||||
HashTable *shared_statics = op_array->static_variables;
|
||||
|
||||
ALLOC_HASHTABLE(op_array->static_variables);
|
||||
GC_REFCOUNT(op_array->static_variables) = 1;
|
||||
GC_TYPE(op_array->static_variables) = IS_ARRAY;
|
||||
zend_hash_clone_zval(op_array->static_variables, shared_statics, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce)
|
||||
{
|
||||
uint idx;
|
||||
Bucket *p, *q;
|
||||
zend_ulong nIndex;
|
||||
zend_class_entry *new_ce;
|
||||
zend_function *new_prototype;
|
||||
zend_op_array *new_entry;
|
||||
|
||||
ht->nTableSize = source->nTableSize;
|
||||
@ -432,31 +411,11 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class
|
||||
ZVAL_PTR(&q->val, ARENA_REALLOC(Z_PTR(p->val)));
|
||||
new_entry = (zend_op_array*)Z_PTR(q->val);
|
||||
|
||||
/* Copy constructor */
|
||||
/* we use refcount to show that op_array is referenced from several places */
|
||||
if (new_entry->refcount != NULL) {
|
||||
accel_xlat_set(Z_PTR(p->val), new_entry);
|
||||
}
|
||||
|
||||
zend_prepare_function_for_execution(new_entry);
|
||||
|
||||
if (old_ce == new_entry->scope) {
|
||||
new_entry->scope = ce;
|
||||
} else {
|
||||
if ((new_ce = accel_xlat_get(new_entry->scope)) != NULL) {
|
||||
new_entry->scope = new_ce;
|
||||
} else {
|
||||
zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name->val, new_entry->function_name->val);
|
||||
}
|
||||
}
|
||||
new_entry->scope = ARENA_REALLOC(new_entry->scope);
|
||||
|
||||
/* update prototype */
|
||||
if (new_entry->prototype) {
|
||||
if ((new_prototype = accel_xlat_get(new_entry->prototype)) != NULL) {
|
||||
new_entry->prototype = new_prototype;
|
||||
} else {
|
||||
zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name->val, new_entry->function_name->val);
|
||||
}
|
||||
new_entry->prototype = ARENA_REALLOC(new_entry->prototype);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -466,7 +425,6 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla
|
||||
uint idx;
|
||||
Bucket *p, *q;
|
||||
zend_ulong nIndex;
|
||||
zend_class_entry *new_ce;
|
||||
zend_property_info *prop_info;
|
||||
|
||||
ht->nTableSize = source->nTableSize;
|
||||
@ -517,24 +475,14 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla
|
||||
prop_info->doc_comment = NULL;
|
||||
}
|
||||
}
|
||||
if (prop_info->ce == old_ce) {
|
||||
prop_info->ce = ce;
|
||||
} else if ((new_ce = accel_xlat_get(prop_info->ce)) != NULL) {
|
||||
prop_info->ce = new_ce;
|
||||
} else {
|
||||
zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name->val, prop_info->name->val);
|
||||
}
|
||||
prop_info->ce = ARENA_REALLOC(prop_info->ce);
|
||||
}
|
||||
}
|
||||
|
||||
#define zend_update_inherited_handler(handler) \
|
||||
{ \
|
||||
if (ce->handler != NULL) { \
|
||||
if ((new_func = accel_xlat_get(ce->handler)) != NULL) { \
|
||||
ce->handler = new_func; \
|
||||
} else { \
|
||||
zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s", ce->name->val); \
|
||||
} \
|
||||
ce->handler = ARENA_REALLOC(ce->handler); \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -543,17 +491,10 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
|
||||
{
|
||||
zend_class_entry *ce = *pce;
|
||||
zend_class_entry *old_ce = ce;
|
||||
zend_class_entry *new_ce;
|
||||
zend_function *new_func;
|
||||
|
||||
*pce = ce = ARENA_REALLOC(old_ce);
|
||||
ce->refcount = 1;
|
||||
|
||||
if (old_ce->refcount != 1) {
|
||||
/* this class is not used as a parent for any other classes */
|
||||
accel_xlat_set(old_ce, ce);
|
||||
}
|
||||
|
||||
if (old_ce->default_properties_table) {
|
||||
int i;
|
||||
|
||||
@ -603,11 +544,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
|
||||
}
|
||||
|
||||
if (ce->parent) {
|
||||
if ((new_ce = accel_xlat_get(ce->parent)) != NULL) {
|
||||
ce->parent = new_ce;
|
||||
} else {
|
||||
zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s", ce->name->val);
|
||||
}
|
||||
ce->parent = ARENA_REALLOC(ce->parent);
|
||||
}
|
||||
|
||||
zend_update_inherited_handler(constructor);
|
||||
@ -718,21 +655,14 @@ static void zend_accel_function_hash_copy(HashTable *target, HashTable *source)
|
||||
for (idx = 0; idx < source->nNumUsed; idx++) {
|
||||
p = source->arData + idx;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF) continue;
|
||||
if (p->key) {
|
||||
t = zend_hash_add(target, p->key, &p->val);
|
||||
if (UNEXPECTED(t == NULL)) {
|
||||
if (p->key->len > 0 && p->key->val[0] == 0) {
|
||||
/* Mangled key */
|
||||
t = zend_hash_update(target, p->key, &p->val);
|
||||
} else {
|
||||
t = zend_hash_find(target, p->key);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t = zend_hash_index_add(target, p->h, &p->val);
|
||||
if (UNEXPECTED(t == NULL)) {
|
||||
t = zend_hash_index_find(target, p->h);
|
||||
ZEND_ASSERT(p->key);
|
||||
t = zend_hash_add(target, p->key, &p->val);
|
||||
if (UNEXPECTED(t == NULL)) {
|
||||
if (p->key->len > 0 && p->key->val[0] == 0) {
|
||||
/* Mangled key */
|
||||
t = zend_hash_update(target, p->key, &p->val);
|
||||
} else {
|
||||
t = zend_hash_find(target, p->key);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
@ -767,26 +697,18 @@ static void zend_accel_function_hash_copy_from_shm(HashTable *target, HashTable
|
||||
for (idx = 0; idx < source->nNumUsed; idx++) {
|
||||
p = source->arData + idx;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF) continue;
|
||||
if (p->key) {
|
||||
t = zend_hash_add(target, p->key, &p->val);
|
||||
if (UNEXPECTED(t == NULL)) {
|
||||
if (p->key->len > 0 && p->key->val[0] == 0) {
|
||||
/* Mangled key */
|
||||
t = zend_hash_update(target, p->key, &p->val);
|
||||
} else {
|
||||
t = zend_hash_find(target, p->key);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t = zend_hash_index_add(target, p->h, &p->val);
|
||||
if (UNEXPECTED(t == NULL)) {
|
||||
t = zend_hash_index_find(target, p->h);
|
||||
ZEND_ASSERT(p->key);
|
||||
t = zend_hash_add(target, p->key, &p->val);
|
||||
if (UNEXPECTED(t == NULL)) {
|
||||
if (p->key->len > 0 && p->key->val[0] == 0) {
|
||||
/* Mangled key */
|
||||
t = zend_hash_update(target, p->key, &p->val);
|
||||
} else {
|
||||
t = zend_hash_find(target, p->key);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
Z_PTR_P(t) = ARENA_REALLOC(Z_PTR(p->val));
|
||||
zend_prepare_function_for_execution((zend_op_array*)Z_PTR_P(t));
|
||||
}
|
||||
target->nInternalPointer = target->nNumOfElements ? 0 : INVALID_IDX;
|
||||
return;
|
||||
@ -818,24 +740,15 @@ static void zend_accel_class_hash_copy(HashTable *target, HashTable *source, uni
|
||||
for (idx = 0; idx < source->nNumUsed; idx++) {
|
||||
p = source->arData + idx;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF) continue;
|
||||
if (p->key) {
|
||||
t = zend_hash_add(target, p->key, &p->val);
|
||||
if (UNEXPECTED(t == NULL)) {
|
||||
if (p->key->len > 0 && p->key->val[0] == 0) {
|
||||
/* Mangled key - ignore and wait for runtime */
|
||||
continue;
|
||||
} else if (!ZCG(accel_directives).ignore_dups) {
|
||||
t = zend_hash_find(target, p->key);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t = zend_hash_index_add(target, p->h, &p->val);
|
||||
if (UNEXPECTED(t == NULL)) {
|
||||
if (!ZCG(accel_directives).ignore_dups) {
|
||||
t = zend_hash_index_find(target,p->h);
|
||||
goto failure;
|
||||
}
|
||||
ZEND_ASSERT(p->key);
|
||||
t = zend_hash_add(target, p->key, &p->val);
|
||||
if (UNEXPECTED(t == NULL)) {
|
||||
if (p->key->len > 0 && p->key->val[0] == 0) {
|
||||
/* Mangled key - ignore and wait for runtime */
|
||||
continue;
|
||||
} else if (!ZCG(accel_directives).ignore_dups) {
|
||||
t = zend_hash_find(target, p->key);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
if (pCopyConstructor) {
|
||||
@ -853,6 +766,34 @@ failure:
|
||||
zend_error(E_ERROR, "Cannot redeclare class %s", ce1->name->val);
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
#include <mmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
static zend_always_inline void fast_memcpy(void *dest, const void *src, size_t size)
|
||||
{
|
||||
__m128i *dqdest = (__m128i*)dest;
|
||||
const __m128i *dqsrc = (const __m128i*)src;
|
||||
const __m128i *end = (const __m128i*)((const char*)src + size);
|
||||
|
||||
do {
|
||||
_mm_prefetch(dqsrc + 4, _MM_HINT_NTA);
|
||||
_mm_prefetch(dqsrc + 6, _MM_HINT_NTA);
|
||||
|
||||
__m128i xmm0 = _mm_load_si128(dqsrc + 0);
|
||||
__m128i xmm1 = _mm_load_si128(dqsrc + 1);
|
||||
__m128i xmm2 = _mm_load_si128(dqsrc + 2);
|
||||
__m128i xmm3 = _mm_load_si128(dqsrc + 3);
|
||||
dqsrc += 4;
|
||||
_mm_stream_si128(dqdest + 0, xmm0);
|
||||
_mm_stream_si128(dqdest + 1, xmm1);
|
||||
_mm_stream_si128(dqdest + 2, xmm2);
|
||||
_mm_stream_si128(dqdest + 3, xmm3);
|
||||
dqdest += 4;
|
||||
} while (dqsrc != end);
|
||||
}
|
||||
#endif
|
||||
|
||||
zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory)
|
||||
{
|
||||
zend_op_array *op_array;
|
||||
@ -866,8 +807,15 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script,
|
||||
ZCG(current_persistent_script) = persistent_script;
|
||||
ZCG(arena_mem) = NULL;
|
||||
if (EXPECTED(persistent_script->arena_size)) {
|
||||
#ifdef __SSE2__
|
||||
/* Target address must be aligned to 64-byte boundary */
|
||||
ZCG(arena_mem) = zend_arena_alloc(&CG(arena), persistent_script->arena_size + 64);
|
||||
ZCG(arena_mem) = (void*)(((zend_uintptr_t)ZCG(arena_mem) + 63L) & ~63L);
|
||||
fast_memcpy(ZCG(arena_mem), persistent_script->arena_mem, persistent_script->arena_size);
|
||||
#else
|
||||
ZCG(arena_mem) = zend_arena_alloc(&CG(arena), persistent_script->arena_size);
|
||||
memcpy(ZCG(arena_mem), persistent_script->arena_mem, persistent_script->arena_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Copy all the necessary stuff from shared memory to regular memory, and protect the shared script */
|
||||
@ -880,8 +828,6 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script,
|
||||
zend_accel_function_hash_copy_from_shm(CG(function_table), &persistent_script->function_table);
|
||||
}
|
||||
|
||||
zend_prepare_function_for_execution(op_array);
|
||||
|
||||
/* Register __COMPILER_HALT_OFFSET__ constant */
|
||||
if (persistent_script->compiler_halt_offset != 0 &&
|
||||
persistent_script->full_path) {
|
||||
|
@ -204,6 +204,7 @@ static void zend_persist_zval(zval *z)
|
||||
/* make immutable array */
|
||||
Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
|
||||
GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
|
||||
GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE;
|
||||
Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
|
||||
}
|
||||
}
|
||||
@ -229,6 +230,63 @@ static void zend_persist_zval(zval *z)
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_persist_zval_static(zval *z)
|
||||
{
|
||||
zend_uchar flags;
|
||||
void *new_ptr;
|
||||
|
||||
switch (Z_TYPE_P(z)) {
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
flags = Z_GC_FLAGS_P(z) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT);
|
||||
zend_accel_store_interned_string(Z_STR_P(z));
|
||||
Z_GC_FLAGS_P(z) |= flags;
|
||||
Z_TYPE_FLAGS_P(z) &= ~(IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z));
|
||||
if (new_ptr) {
|
||||
Z_ARR_P(z) = new_ptr;
|
||||
Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
|
||||
} else {
|
||||
if (Z_IMMUTABLE_P(z)) {
|
||||
Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array));
|
||||
zend_hash_persist_immutable(Z_ARRVAL_P(z));
|
||||
} else {
|
||||
GC_REMOVE_FROM_BUFFER(Z_ARR_P(z));
|
||||
zend_accel_store(Z_ARR_P(z), sizeof(zend_array));
|
||||
zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval);
|
||||
/* make immutable array */
|
||||
Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
|
||||
GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
|
||||
GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE;
|
||||
Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IS_REFERENCE:
|
||||
new_ptr = zend_shared_alloc_get_xlat_entry(Z_REF_P(z));
|
||||
if (new_ptr) {
|
||||
Z_REF_P(z) = new_ptr;
|
||||
} else {
|
||||
zend_accel_store(Z_REF_P(z), sizeof(zend_reference));
|
||||
zend_persist_zval(Z_REFVAL_P(z));
|
||||
}
|
||||
break;
|
||||
case IS_CONSTANT_AST:
|
||||
new_ptr = zend_shared_alloc_get_xlat_entry(Z_AST_P(z));
|
||||
if (new_ptr) {
|
||||
Z_AST_P(z) = new_ptr;
|
||||
} else {
|
||||
zend_accel_store(Z_AST_P(z), sizeof(zend_ast_ref));
|
||||
Z_ASTVAL_P(z) = zend_persist_ast(Z_ASTVAL_P(z));
|
||||
Z_TYPE_FLAGS_P(z) = IS_TYPE_CONSTANT | IS_TYPE_IMMUTABLE;
|
||||
GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_persist_zval_const(zval *z)
|
||||
{
|
||||
zend_uchar flags;
|
||||
@ -258,6 +316,7 @@ static void zend_persist_zval_const(zval *z)
|
||||
/* make immutable array */
|
||||
Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
|
||||
GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
|
||||
GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE;
|
||||
Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
|
||||
}
|
||||
}
|
||||
@ -293,7 +352,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
|
||||
return;
|
||||
}
|
||||
|
||||
if (--(*op_array->refcount) == 0) {
|
||||
if (op_array->refcount && --(*op_array->refcount) == 0) {
|
||||
efree(op_array->refcount);
|
||||
}
|
||||
op_array->refcount = NULL;
|
||||
@ -313,8 +372,18 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
|
||||
}
|
||||
|
||||
if (op_array->static_variables) {
|
||||
zend_hash_persist(op_array->static_variables, zend_persist_zval);
|
||||
zend_accel_store(op_array->static_variables, sizeof(HashTable));
|
||||
HashTable *stored = zend_shared_alloc_get_xlat_entry(op_array->static_variables);
|
||||
|
||||
if (stored) {
|
||||
op_array->static_variables = stored;
|
||||
} else {
|
||||
zend_hash_persist(op_array->static_variables, zend_persist_zval_static);
|
||||
zend_accel_store(op_array->static_variables, sizeof(HashTable));
|
||||
/* make immutable array */
|
||||
GC_REFCOUNT(op_array->static_variables) = 2;
|
||||
GC_TYPE_INFO(op_array->static_variables) = IS_ARRAY | (IS_ARRAY_IMMUTABLE << 8);
|
||||
op_array->static_variables->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
|
||||
}
|
||||
}
|
||||
|
||||
if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) {
|
||||
@ -495,8 +564,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
|
||||
if (op_array->scope && op_array->prototype) {
|
||||
if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->prototype))) {
|
||||
op_array->prototype = (union _zend_function*)persist_ptr;
|
||||
/* we use refcount to show that op_array is referenced from several places */
|
||||
op_array->prototype->op_array.refcount++;
|
||||
}
|
||||
} else {
|
||||
op_array->prototype = NULL;
|
||||
@ -661,63 +728,47 @@ static int zend_update_parent_ce(zval *zv)
|
||||
|
||||
if (ce->parent) {
|
||||
ce->parent = zend_shared_alloc_get_xlat_entry(ce->parent);
|
||||
/* We use refcount to show if the class is used as a parent */
|
||||
ce->parent->refcount++;
|
||||
}
|
||||
|
||||
/* update methods */
|
||||
if (ce->constructor) {
|
||||
ce->constructor = zend_shared_alloc_get_xlat_entry(ce->constructor);
|
||||
/* we use refcount to show that op_array is referenced from several places */
|
||||
ce->constructor->op_array.refcount++;
|
||||
}
|
||||
if (ce->destructor) {
|
||||
ce->destructor = zend_shared_alloc_get_xlat_entry(ce->destructor);
|
||||
ce->destructor->op_array.refcount++;
|
||||
}
|
||||
if (ce->clone) {
|
||||
ce->clone = zend_shared_alloc_get_xlat_entry(ce->clone);
|
||||
ce->clone->op_array.refcount++;
|
||||
}
|
||||
if (ce->__get) {
|
||||
ce->__get = zend_shared_alloc_get_xlat_entry(ce->__get);
|
||||
ce->__get->op_array.refcount++;
|
||||
}
|
||||
if (ce->__set) {
|
||||
ce->__set = zend_shared_alloc_get_xlat_entry(ce->__set);
|
||||
ce->__set->op_array.refcount++;
|
||||
}
|
||||
if (ce->__call) {
|
||||
ce->__call = zend_shared_alloc_get_xlat_entry(ce->__call);
|
||||
ce->__call->op_array.refcount++;
|
||||
}
|
||||
if (ce->serialize_func) {
|
||||
ce->serialize_func = zend_shared_alloc_get_xlat_entry(ce->serialize_func);
|
||||
ce->serialize_func->op_array.refcount++;
|
||||
}
|
||||
if (ce->unserialize_func) {
|
||||
ce->unserialize_func = zend_shared_alloc_get_xlat_entry(ce->unserialize_func);
|
||||
ce->unserialize_func->op_array.refcount++;
|
||||
}
|
||||
if (ce->__isset) {
|
||||
ce->__isset = zend_shared_alloc_get_xlat_entry(ce->__isset);
|
||||
ce->__isset->op_array.refcount++;
|
||||
}
|
||||
if (ce->__unset) {
|
||||
ce->__unset = zend_shared_alloc_get_xlat_entry(ce->__unset);
|
||||
ce->__unset->op_array.refcount++;
|
||||
}
|
||||
if (ce->__tostring) {
|
||||
ce->__tostring = zend_shared_alloc_get_xlat_entry(ce->__tostring);
|
||||
ce->__tostring->op_array.refcount++;
|
||||
}
|
||||
if (ce->__callstatic) {
|
||||
ce->__callstatic = zend_shared_alloc_get_xlat_entry(ce->__callstatic);
|
||||
ce->__callstatic->op_array.refcount++;
|
||||
}
|
||||
if (ce->__debugInfo) {
|
||||
ce->__debugInfo = zend_shared_alloc_get_xlat_entry(ce->__debugInfo);
|
||||
ce->__debugInfo->op_array.refcount++;
|
||||
}
|
||||
zend_hash_apply(&ce->properties_info, (apply_func_t) zend_update_property_info_ce);
|
||||
return 0;
|
||||
@ -739,6 +790,11 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script
|
||||
*key = zend_accel_memdup(*key, key_length + 1);
|
||||
zend_accel_store_string(script->full_path);
|
||||
|
||||
#ifdef __SSE2__
|
||||
/* Align to 64-byte boundary */
|
||||
ZCG(mem) = (void*)(((zend_uintptr_t)ZCG(mem) + 63L) & ~63L);
|
||||
#endif
|
||||
|
||||
script->arena_mem = ZCG(arena_mem) = ZCG(mem);
|
||||
ZCG(mem) = (void*)((char*)ZCG(mem) + script->arena_size);
|
||||
|
||||
|
@ -150,8 +150,13 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
|
||||
}
|
||||
|
||||
if (op_array->static_variables) {
|
||||
ADD_DUP_SIZE(op_array->static_variables, sizeof(HashTable));
|
||||
zend_hash_persist_calc(op_array->static_variables, zend_persist_zval_calc);
|
||||
if (!zend_shared_alloc_get_xlat_entry(op_array->static_variables)) {
|
||||
HashTable *old = op_array->static_variables;
|
||||
|
||||
ADD_DUP_SIZE(op_array->static_variables, sizeof(HashTable));
|
||||
zend_hash_persist_calc(op_array->static_variables, zend_persist_zval_calc);
|
||||
zend_shared_alloc_register_xlat_entry(old, op_array->static_variables);
|
||||
}
|
||||
}
|
||||
|
||||
if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) {
|
||||
@ -356,10 +361,20 @@ uint zend_accel_script_persist_calc(zend_persistent_script *new_persistent_scrip
|
||||
ADD_DUP_SIZE(key, key_length + 1);
|
||||
ADD_STRING(new_persistent_script->full_path);
|
||||
|
||||
#ifdef __SSE2__
|
||||
/* Align size to 64-byte boundary */
|
||||
new_persistent_script->size = (new_persistent_script->size + 63) & ~63;
|
||||
#endif
|
||||
|
||||
zend_accel_persist_class_table_calc(&new_persistent_script->class_table);
|
||||
zend_hash_persist_calc(&new_persistent_script->function_table, zend_persist_op_array_calc);
|
||||
zend_persist_op_array_calc_ex(&new_persistent_script->main_op_array);
|
||||
|
||||
#ifdef __SSE2__
|
||||
/* Align size to 64-byte boundary */
|
||||
new_persistent_script->arena_size = (new_persistent_script->arena_size + 63) & ~63;
|
||||
#endif
|
||||
|
||||
new_persistent_script->size += new_persistent_script->arena_size;
|
||||
|
||||
ZCG(current_persistent_script) = NULL;
|
||||
|
@ -91,7 +91,7 @@ typedef struct _handler_entry {
|
||||
|
||||
typedef struct _zend_shared_memory_state {
|
||||
int *positions; /* current positions for each segment */
|
||||
int shared_free; /* amount of free shared memory */
|
||||
size_t shared_free; /* amount of free shared memory */
|
||||
} zend_shared_memory_state;
|
||||
|
||||
typedef struct _zend_smm_shared_globals {
|
||||
|
@ -1852,6 +1852,12 @@ ZEND_METHOD(reflection_function, getStaticVariables)
|
||||
/* Return an empty array in case no static variables exist */
|
||||
array_init(return_value);
|
||||
if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) {
|
||||
if (GC_REFCOUNT(fptr->op_array.static_variables) > 1) {
|
||||
if (!(GC_FLAGS(fptr->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_REFCOUNT(fptr->op_array.static_variables)--;
|
||||
}
|
||||
fptr->op_array.static_variables = zend_array_dup(fptr->op_array.static_variables);
|
||||
}
|
||||
zend_hash_apply_with_argument(fptr->op_array.static_variables, (apply_func_arg_t) zval_update_constant_inline_change, fptr->common.scope);
|
||||
zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, zval_add_ref);
|
||||
}
|
||||
|
@ -192,18 +192,21 @@ static inline void spl_filesystem_object_get_file_name(spl_filesystem_object *in
|
||||
{
|
||||
char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH;
|
||||
|
||||
if (!intern->file_name) {
|
||||
switch (intern->type) {
|
||||
switch (intern->type) {
|
||||
case SPL_FS_INFO:
|
||||
case SPL_FS_FILE:
|
||||
php_error_docref(NULL, E_ERROR, "Object not initialized");
|
||||
if (!intern->file_name) {
|
||||
php_error_docref(NULL, E_ERROR, "Object not initialized");
|
||||
}
|
||||
break;
|
||||
case SPL_FS_DIR:
|
||||
if (intern->file_name) {
|
||||
efree(intern->file_name);
|
||||
}
|
||||
intern->file_name_len = (int)spprintf(&intern->file_name, 0, "%s%c%s",
|
||||
spl_filesystem_object_get_path(intern, NULL),
|
||||
slash, intern->u.dir.entry.d_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
|
@ -770,6 +770,7 @@ SPL_METHOD(SplObjectStorage, serialize)
|
||||
/* members */
|
||||
smart_str_appendl(&buf, "m:", 2);
|
||||
ZVAL_ARR(&members, zend_array_dup(zend_std_get_properties(getThis())));
|
||||
zend_hash_str_del(Z_ARRVAL(members), "\x00gcdata", sizeof("\x00gcdata") - 1);
|
||||
php_var_serialize(&buf, &members, &var_hash); /* finishes the string */
|
||||
zval_ptr_dtor(&members);
|
||||
|
||||
|
42
ext/spl/tests/bug68557.phpt
Normal file
42
ext/spl/tests/bug68557.phpt
Normal file
@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
Bug #68557 (SplFileInfo::getPathname() may be broken)
|
||||
--FILE--
|
||||
<?php
|
||||
mkdir(__DIR__ . DIRECTORY_SEPARATOR . 'tmp');
|
||||
touch(__DIR__ . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . 'a');
|
||||
touch(__DIR__ . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . 'b');
|
||||
|
||||
$d = new DirectoryIterator(__DIR__ . DIRECTORY_SEPARATOR . 'tmp');
|
||||
|
||||
$d->seek(0);
|
||||
$path0 = $d->current()->getPathname();
|
||||
|
||||
$d->seek(1);
|
||||
$path1 = $d->current()->getPathname();
|
||||
|
||||
$d->seek(2);
|
||||
$path2 = $d->current()->getPathname();
|
||||
|
||||
$d->seek(0);
|
||||
var_dump($path0 === $d->current()->getPathname());
|
||||
|
||||
$d->seek(1);
|
||||
var_dump($path1 === $d->current()->getPathname());
|
||||
|
||||
$d->seek(2);
|
||||
var_dump($path2 === $d->current()->getPathname());
|
||||
|
||||
$d->seek(0);
|
||||
var_dump($path0 === $d->current()->getPathname());
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . 'a');
|
||||
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . 'b');
|
||||
rmdir(__DIR__ . DIRECTORY_SEPARATOR . 'tmp');
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
22
ext/spl/tests/bug69108.phpt
Normal file
22
ext/spl/tests/bug69108.phpt
Normal file
@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
Bug #69108 ("Segmentation fault" when (de)serializing SplObjectStorage)
|
||||
--INI--
|
||||
zend.enable_gc=1
|
||||
--FILE--
|
||||
<?php
|
||||
$a = array();
|
||||
$b = new SplObjectStorage();
|
||||
for ($i = 10000; $i > 0; $i--) {
|
||||
$object = new StdClass();
|
||||
$a[] = $object;
|
||||
$b->attach($object);
|
||||
}
|
||||
|
||||
$c = serialize(array($a, $b));
|
||||
$d = unserialize($c);
|
||||
|
||||
unset($d);
|
||||
echo "ok";
|
||||
?>
|
||||
--EXPECT--
|
||||
ok
|
@ -925,12 +925,12 @@ PHP_FUNCTION(current)
|
||||
zval *entry;
|
||||
|
||||
#ifndef FAST_ZPP
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H", &array) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
|
||||
Z_PARAM_ARRAY_OR_OBJECT_HT(array)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
#endif
|
||||
|
||||
@ -953,12 +953,12 @@ PHP_FUNCTION(key)
|
||||
HashTable *array;
|
||||
|
||||
#ifndef FAST_ZPP
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H", &array) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1)
|
||||
Z_PARAM_ARRAY_OR_OBJECT_HT(array)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
#endif
|
||||
|
||||
|
@ -289,11 +289,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_reset, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_current, 0)
|
||||
ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg)
|
||||
ZEND_ARG_INFO(0, arg)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_key, 0)
|
||||
ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg)
|
||||
ZEND_ARG_INFO(0, arg)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_min, 0, 0, 1)
|
||||
|
@ -311,8 +311,7 @@ PHP_MINIT_FUNCTION(browscap) /* {{{ */
|
||||
char *browscap = INI_STR("browscap");
|
||||
|
||||
#ifdef ZTS
|
||||
ts_allocate_id(&browscap_globals_id, sizeof(browser_data),
|
||||
(ts_allocate_ctor) browscap_globals_ctor, NULL);
|
||||
ts_allocate_id(&browscap_globals_id, sizeof(browser_data), (ts_allocate_ctor) browscap_globals_ctor, NULL);
|
||||
#endif
|
||||
/* ctor call not really needed for non-ZTS */
|
||||
|
||||
|
@ -359,11 +359,7 @@ PHP_FUNCTION(flock)
|
||||
/* flock_values contains all possible actions if (operation & 4) we won't block on the lock */
|
||||
act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0);
|
||||
if (php_stream_lock(stream, act)) {
|
||||
#ifdef PHP_WIN32
|
||||
if (operation && errno == ERROR_INVALID_BLOCK && wouldblock) {
|
||||
#else
|
||||
if (operation && errno == EWOULDBLOCK && wouldblock) {
|
||||
#endif
|
||||
ZVAL_LONG(wouldblock, 1);
|
||||
}
|
||||
RETURN_FALSE;
|
||||
|
@ -125,8 +125,12 @@ PHPAPI int php_flock(int fd, int operation)
|
||||
DWORD low = 1, high = 0;
|
||||
OVERLAPPED offset =
|
||||
{0, 0, 0, 0, NULL};
|
||||
if (hdl < 0)
|
||||
DWORD err;
|
||||
|
||||
if (hdl < 0) {
|
||||
_set_errno(EBADF);
|
||||
return -1; /* error in file descriptor */
|
||||
}
|
||||
/* bug for bug compatible with Unix */
|
||||
UnlockFileEx(hdl, 0, low, high, &offset);
|
||||
switch (operation & ~LOCK_NB) { /* translate to LockFileEx() op */
|
||||
@ -146,12 +150,14 @@ PHPAPI int php_flock(int fd, int operation)
|
||||
default: /* default */
|
||||
break;
|
||||
}
|
||||
/* Under Win32 MT library, errno is not a variable but a function call,
|
||||
* which cannot be assigned to.
|
||||
*/
|
||||
#if !defined(PHP_WIN32)
|
||||
errno = EINVAL; /* bad call */
|
||||
#endif
|
||||
|
||||
err = GetLastError();
|
||||
if (ERROR_LOCK_VIOLATION == err || ERROR_SHARING_VIOLATION == err) {
|
||||
_set_errno(EWOULDBLOCK);
|
||||
} else {
|
||||
_set_errno(EINVAL); /* bad call */
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -459,9 +459,13 @@ array(5) {
|
||||
|
||||
-- Testing variation: when array is unset --
|
||||
|
||||
Notice: Undefined variable: unset_array in %s on line %d
|
||||
|
||||
Warning: current() expects parameter 1 to be array, null given in %s on line %d
|
||||
NULL
|
||||
|
||||
Notice: Undefined variable: unset_array in %s on line %d
|
||||
|
||||
Warning: key() expects parameter 1 to be array, null given in %s on line %d
|
||||
NULL
|
||||
|
||||
|
52
main/main.c
52
main/main.c
@ -1919,8 +1919,6 @@ static size_t php_output_wrapper(const char *str, size_t str_length)
|
||||
static void core_globals_ctor(php_core_globals *core_globals)
|
||||
{
|
||||
memset(core_globals, 0, sizeof(*core_globals));
|
||||
|
||||
php_startup_ticks();
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
@ -2034,11 +2032,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
|
||||
int retval = SUCCESS, module_number=0; /* for REGISTER_INI_ENTRIES() */
|
||||
char *php_os;
|
||||
zend_module_entry *module;
|
||||
#ifdef ZTS
|
||||
zend_executor_globals *executor_globals;
|
||||
void ***tsrm_ls;
|
||||
php_core_globals *core_globals;
|
||||
#endif
|
||||
|
||||
#if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK))
|
||||
WORD wVersionRequested = MAKEWORD(2, 0);
|
||||
@ -2057,11 +2050,11 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
|
||||
_CrtSetReportMode(_CRT_ASSERT, 0);
|
||||
#endif
|
||||
#else
|
||||
php_os=PHP_OS;
|
||||
php_os = PHP_OS;
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
tsrm_ls = ts_resource(0);
|
||||
(void)ts_resource(0);
|
||||
#endif
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
@ -2081,6 +2074,17 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
|
||||
|
||||
php_output_startup();
|
||||
|
||||
#ifdef ZTS
|
||||
ts_allocate_id(&core_globals_id, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor);
|
||||
php_startup_ticks();
|
||||
#ifdef PHP_WIN32
|
||||
ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor);
|
||||
#endif
|
||||
#else
|
||||
php_startup_ticks();
|
||||
#endif
|
||||
gc_globals_ctor();
|
||||
|
||||
zuf.error_function = php_error_cb;
|
||||
zuf.printf_function = php_printf;
|
||||
zuf.write_function = php_output_wrapper;
|
||||
@ -2098,18 +2102,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
|
||||
zuf.resolve_path_function = php_resolve_path_for_zend;
|
||||
zend_startup(&zuf, NULL);
|
||||
|
||||
#ifdef ZTS
|
||||
executor_globals = ts_resource(executor_globals_id);
|
||||
ts_allocate_id(&core_globals_id, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor);
|
||||
core_globals = ts_resource(core_globals_id);
|
||||
#ifdef PHP_WIN32
|
||||
ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor);
|
||||
#endif
|
||||
#else
|
||||
php_startup_ticks();
|
||||
#endif
|
||||
gc_globals_ctor();
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
{
|
||||
OSVERSIONINFOEX *osvi = &EG(windows_version_info);
|
||||
@ -2122,24 +2114,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
|
||||
}
|
||||
}
|
||||
#endif
|
||||
EG(bailout) = NULL;
|
||||
EG(error_reporting) = E_ALL & ~E_NOTICE;
|
||||
PG(header_is_being_sent) = 0;
|
||||
SG(request_info).headers_only = 0;
|
||||
SG(request_info).argv0 = NULL;
|
||||
SG(request_info).argc=0;
|
||||
SG(request_info).argv=(char **)NULL;
|
||||
PG(connection_status) = PHP_CONNECTION_NORMAL;
|
||||
PG(during_request_startup) = 0;
|
||||
PG(last_error_message) = NULL;
|
||||
PG(last_error_file) = NULL;
|
||||
PG(last_error_lineno) = 0;
|
||||
EG(error_handling) = EH_NORMAL;
|
||||
EG(exception_class) = NULL;
|
||||
PG(disable_functions) = NULL;
|
||||
PG(disable_classes) = NULL;
|
||||
EG(exception) = NULL;
|
||||
EG(objects_store).object_buckets = NULL;
|
||||
|
||||
#if HAVE_SETLOCALE
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
@ -180,6 +180,7 @@ PHPAPI void php_output_deactivate(void)
|
||||
php_output_handler **handler = NULL;
|
||||
|
||||
if ((OG(flags) & PHP_OUTPUT_ACTIVATED)) {
|
||||
php_output_header();
|
||||
|
||||
OG(flags) ^= PHP_OUTPUT_ACTIVATED;
|
||||
OG(active) = NULL;
|
||||
|
@ -1390,10 +1390,12 @@ char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex )
|
||||
off = pReq->m_pHeaderIndex->m_headerOff[ headerIndex ];
|
||||
if ( !off )
|
||||
return NULL;
|
||||
if ( *(pReq->m_pHttpHeader + off +
|
||||
pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) )
|
||||
*( pReq->m_pHttpHeader + off +
|
||||
pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0;
|
||||
if ( *(pReq->m_pHttpHeader + off
|
||||
+ pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) )
|
||||
{
|
||||
*( pReq->m_pHttpHeader + off
|
||||
+ pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0;
|
||||
}
|
||||
return pReq->m_pHttpHeader + off;
|
||||
}
|
||||
|
||||
@ -1830,12 +1832,21 @@ ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t le
|
||||
static char * GetHeaderVar( LSAPI_Request * pReq, const char * name )
|
||||
{
|
||||
int i;
|
||||
char * pValue;
|
||||
for( i = 0; i < H_TRANSFER_ENCODING; ++i )
|
||||
{
|
||||
if ( pReq->m_pHeaderIndex->m_headerOff[i] )
|
||||
{
|
||||
if ( strcmp( name, CGI_HEADERS[i] ) == 0 )
|
||||
return pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i];
|
||||
{
|
||||
pValue = pReq->m_pHttpHeader
|
||||
+ pReq->m_pHeaderIndex->m_headerOff[i];
|
||||
if ( *(pValue + pReq->m_pHeaderIndex->m_headerLen[i]) != '\0')
|
||||
{
|
||||
*(pValue + pReq->m_pHeaderIndex->m_headerLen[i]) = '\0';
|
||||
}
|
||||
return pValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 )
|
||||
@ -1862,7 +1873,15 @@ static char * GetHeaderVar( LSAPI_Request * pReq, const char * name )
|
||||
++p; ++pKey;
|
||||
}
|
||||
if (( pKey == pKeyEnd )&& (!*p ))
|
||||
return pReq->m_pHttpHeader + pCur->valueOff;
|
||||
{
|
||||
pValue = pReq->m_pHttpHeader + pCur->valueOff;
|
||||
|
||||
if ( *(pValue + pCur->valueLen) != '\0')
|
||||
{
|
||||
*(pValue + pCur->valueLen) = '\0';
|
||||
}
|
||||
return pValue;
|
||||
}
|
||||
++pCur;
|
||||
}
|
||||
}
|
||||
|
@ -1454,7 +1454,10 @@ next:
|
||||
PHPDBG_G(last_line) = execute_data->opline->lineno;
|
||||
|
||||
/* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */
|
||||
if (execute_data->opline->opcode == ZEND_DO_FCALL && execute_data->func->type == ZEND_USER_FUNCTION) {
|
||||
if ((execute_data->opline->opcode == ZEND_DO_FCALL ||
|
||||
execute_data->opline->opcode == ZEND_DO_UCALL ||
|
||||
execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME) &&
|
||||
execute_data->func->type == ZEND_USER_FUNCTION) {
|
||||
zend_execute_ex = execute_ex;
|
||||
}
|
||||
PHPDBG_G(vmret) = execute_data->opline->handler(execute_data);
|
||||
|
@ -1,5 +0,0 @@
|
||||
@if exist ..\ZendEngine2\OBJECTS2_HOWTO (
|
||||
move ..\Zend ..\ZendEngine1
|
||||
move ..\ZendEngine2 ..\Zend
|
||||
echo "PLEASE RESTART VISUAL C++ TO RELOAD THE ZEND PROJECT."
|
||||
exit 1 )
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Program: Unix compatibility routines
|
||||
*
|
||||
* Author: Mark Crispin
|
||||
* Networks and Distributed Computing
|
||||
* Computing & Communications
|
||||
* University of Washington
|
||||
* Administration Building, AG-44
|
||||
* Seattle, WA 98195
|
||||
* Internet: MRC@CAC.Washington.EDU
|
||||
*
|
||||
* Date: 14 September 1996
|
||||
* Last Edited: 14 August 1997
|
||||
*
|
||||
* Copyright 1997 by the University of Washington
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted, provided
|
||||
* that the above copyright notice appears in all copies and that both the
|
||||
* above copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the University of Washington not be
|
||||
* used in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. This software is made available
|
||||
* "as is", and
|
||||
* THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
|
||||
* WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
|
||||
* NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
|
||||
* (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* DEDICATION
|
||||
|
||||
* This file is dedicated to my dog, Unix, also known as Yun-chan and
|
||||
* Unix J. Terwilliker Jehosophat Aloysius Monstrosity Animal Beast. Unix
|
||||
* passed away at the age of 11 1/2 on September 14, 1996, 12:18 PM PDT, after
|
||||
* a two-month bout with cirrhosis of the liver.
|
||||
*
|
||||
* He was a dear friend, and I miss him terribly.
|
||||
*
|
||||
* Lift a leg, Yunie. Luv ya forever!!!!
|
||||
*/
|
||||
|
||||
#include "php.h"
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include <errno.h>
|
||||
#include "flock.h"
|
||||
|
||||
PHPAPI int flock(int fd, int op)
|
||||
{
|
||||
HANDLE hdl = (HANDLE) _get_osfhandle(fd);
|
||||
DWORD low = 1, high = 0;
|
||||
OVERLAPPED offset =
|
||||
{0, 0, 0, 0, NULL};
|
||||
if (hdl < 0)
|
||||
return -1; /* error in file descriptor */
|
||||
/* bug for bug compatible with Unix */
|
||||
UnlockFileEx(hdl, 0, low, high, &offset);
|
||||
switch (op & ~LOCK_NB) { /* translate to LockFileEx() op */
|
||||
case LOCK_EX: /* exclusive */
|
||||
if (LockFileEx(hdl, LOCKFILE_EXCLUSIVE_LOCK +
|
||||
((op & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0),
|
||||
0, low, high, &offset))
|
||||
return 0;
|
||||
break;
|
||||
case LOCK_SH: /* shared */
|
||||
if (LockFileEx(hdl, ((op & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0),
|
||||
0, low, high, &offset))
|
||||
return 0;
|
||||
break;
|
||||
case LOCK_UN: /* unlock */
|
||||
return 0; /* always succeeds */
|
||||
default: /* default */
|
||||
break;
|
||||
}
|
||||
errno = EINVAL; /* bad call */
|
||||
return -1;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#define fsync _commit
|
||||
#define ftruncate chsize
|
||||
|
||||
/* For flock() emulation */
|
||||
|
||||
#define LOCK_SH 1
|
||||
#define LOCK_EX 2
|
||||
#define LOCK_NB 4
|
||||
#define LOCK_UN 8
|
||||
|
||||
PHPAPI int flock(int fd, int op);
|
Loading…
Reference in New Issue
Block a user