ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
{
USE_OPLINE
- zend_function *op_array;
+ zval *zfunc;
- int closure_is_static, closure_is_being_defined_inside_static_context;
SAVE_OPLINE();
- if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), Z_HASH_P(opline->op1.zv), (void *) &op_array) == FAILURE) ||
- UNEXPECTED(op_array->type != ZEND_USER_FUNCTION)) {
- zend_error_noreturn(E_ERROR, "Base lambda function for closure not found");
- }
+ zfunc = zend_hash_find(EG(function_table), Z_STR_P(EX_CONSTANT(opline->op1)));
+ ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION);
- closure_is_static = Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC;
- closure_is_being_defined_inside_static_context = EX(func)->common.fn_flags & ZEND_ACC_STATIC;
- if (closure_is_static || closure_is_being_defined_inside_static_context) {
- if (UNEXPECTED((op_array->common.fn_flags & ZEND_ACC_STATIC) ||
- (EX(prev_execute_data) &&
- EX(prev_execute_data)->function_state.function->common.fn_flags & ZEND_ACC_STATIC))) {
- zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(called_scope), NULL TSRMLS_CC);
++ if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||
++ (EX(func)->common.fn_flags & ZEND_ACC_STATIC))) {
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(called_scope), NULL);
} else {
- zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EG(scope), Z_OBJ(EX(This)) ? &EX(This) : NULL);
}
CHECK_EXCEPTION();
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
- CACHE_PTR(opline->op2.literal->cache_slot, ce);
+ CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce);
}
} else {
- ce = EX_T(opline->op2.var).class_entry;
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ if (IS_CONST == IS_CONST &&
+ (value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce)) != NULL) {
+
+ /* check if static properties were destoyed */
+ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
+ value = NULL;
+ }
+
+ goto is_var_return;
+ }
}
- value = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1, ((IS_CONST == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
- if (!value) {
- isset = 0;
+
+ value = zend_std_get_static_property(ce, Z_STR_P(varname), 1);
+
+ if (IS_CONST == IS_CONST && value) {
+ CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce, value);
}
} else {
- target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
- if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
- isset = 0;
- }
+ HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK);
+ value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname));
}
- if (IS_CONST != IS_CONST && varname == &tmp) {
- zval_dtor(&tmp);
+ if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
+ zend_string_release(Z_STR(tmp));
}
- }
-
- if (opline->extended_value & ZEND_ISSET) {
- if (isset && Z_TYPE_PP(value) != IS_NULL) {
- ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1);
- } else {
- ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0);
- }
- } else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (!isset || !i_zend_is_true(*value)) {
- ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1);
- } else {
- ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0);
+is_var_return:
+ if (opline->extended_value & ZEND_ISSET) {
+ result = value && Z_TYPE_P(value) > IS_NULL &&
+ (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL);
+ } else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
+ result = !value || !i_zend_is_true(value);
}
- }
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ ZEND_VM_SMART_BRANCH(result, 1);
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
}
-static int ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_function *op_array;
+ zval *zfunc;
- int closure_is_static, closure_is_being_defined_inside_static_context;
SAVE_OPLINE();
- if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv), Z_HASH_P(opline->op1.zv), (void *) &op_array) == FAILURE) ||
- UNEXPECTED(op_array->type != ZEND_USER_FUNCTION)) {
- zend_error_noreturn(E_ERROR, "Base lambda function for closure not found");
- }
+ zfunc = zend_hash_find(EG(function_table), Z_STR_P(EX_CONSTANT(opline->op1)));
+ ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION);
- closure_is_static = Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC;
- closure_is_being_defined_inside_static_context = EX(func)->common.fn_flags & ZEND_ACC_STATIC;
- if (closure_is_static || closure_is_being_defined_inside_static_context) {
- if (UNEXPECTED((op_array->common.fn_flags & ZEND_ACC_STATIC) ||
- (EX(prev_execute_data) &&
- EX(prev_execute_data)->function_state.function->common.fn_flags & ZEND_ACC_STATIC))) {
- zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(called_scope), NULL TSRMLS_CC);
++ if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||
++ (EX(func)->common.fn_flags & ZEND_ACC_STATIC))) {
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(called_scope), NULL);
} else {
- zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC);
+ zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EG(scope), Z_OBJ(EX(This)) ? &EX(This) : NULL);
}
CHECK_EXCEPTION();