diff options
author | Dmitry Stogov <dmitry@php.net> | 2008-07-14 09:49:03 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2008-07-14 09:49:03 +0000 |
commit | d5ef2f466cb112fd977a71419fa4b67d0aa0a2ac (patch) | |
tree | 2f61549b96e8db664a1467f36ce11772600c86a9 /Zend/zend_vm_execute.h | |
parent | d23342397c14a6efb3e0b1ea20928f81ccc48657 (diff) | |
download | php-git-d5ef2f466cb112fd977a71419fa4b67d0aa0a2ac.tar.gz |
Added support for lambda functions and closures
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r-- | Zend/zend_vm_execute.h | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 23e6849f24..3026f4555b 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -747,6 +747,15 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE } else { function_name = &opline->op2.u.constant; + if (Z_TYPE_P(function_name) == IS_OBJECT && + zend_get_closure(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { + if (EX(object)) { + Z_ADDREF_P(EX(object)); + } + + ZEND_VM_NEXT_OPCODE(); + } + if (Z_TYPE_P(function_name) != IS_STRING) { zend_error_noreturn(E_ERROR, "Function name must be a string"); } @@ -935,6 +944,15 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H } else { function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + if (Z_TYPE_P(function_name) == IS_OBJECT && + zend_get_closure(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { + if (EX(object)) { + Z_ADDREF_P(EX(object)); + } + zval_dtor(free_op2.var); + ZEND_VM_NEXT_OPCODE(); + } + if (Z_TYPE_P(function_name) != IS_STRING) { zend_error_noreturn(E_ERROR, "Function name must be a string"); } @@ -1031,6 +1049,15 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H } else { function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + if (Z_TYPE_P(function_name) == IS_OBJECT && + zend_get_closure(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { + if (EX(object)) { + Z_ADDREF_P(EX(object)); + } + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + ZEND_VM_NEXT_OPCODE(); + } + if (Z_TYPE_P(function_name) != IS_STRING) { zend_error_noreturn(E_ERROR, "Function name must be a string"); } @@ -1155,6 +1182,15 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA } else { function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + if (Z_TYPE_P(function_name) == IS_OBJECT && + zend_get_closure(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { + if (EX(object)) { + Z_ADDREF_P(EX(object)); + } + + ZEND_VM_NEXT_OPCODE(); + } + if (Z_TYPE_P(function_name) != IS_STRING) { zend_error_noreturn(E_ERROR, "Function name must be a string"); } @@ -2875,6 +2911,21 @@ static int ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_op *opline = EX(opline); + zend_op_array *op_array; + + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant), Z_LVAL(opline->op2.u.constant), (void *) &op_array) == FAILURE || + op_array->type != ZEND_USER_FUNCTION) { + zend_error_noreturn(E_ERROR, "Base lambda function for closure not found"); + } + + zend_create_closure(&EX_T(opline->result.u.var).tmp_var, op_array, EG(scope), EG(This) TSRMLS_CC); + + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -33508,6 +33559,31 @@ void zend_init_opcodes_handlers(void) ZEND_JMP_SET_SPEC_CV_HANDLER, ZEND_JMP_SET_SPEC_CV_HANDLER, ZEND_JMP_SET_SPEC_CV_HANDLER, + ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = (opcode_handler_t*)labels; |