diff --git a/vkext/vkext-rpc-tl-serialization.cpp b/vkext/vkext-rpc-tl-serialization.cpp index d7b2e36654..839b26e08f 100644 --- a/vkext/vkext-rpc-tl-serialization.cpp +++ b/vkext/vkext-rpc-tl-serialization.cpp @@ -532,7 +532,7 @@ static zval *create_php_instance(const char *class_name) { return ci; } -static zval *make_query_result_or_error(zval *r, const vkext_rpc::tl::RpcReqError &error, const vkext_rpc::tl::RpcReqResultExtra *header = nullptr, int extra_flags = 0); +static zval *make_query_result_or_error(zval **r, const vkext_rpc::tl::RpcReqError &error, const vkext_rpc::tl::RpcReqResultExtra *header = nullptr, int extra_flags = 0); /** * This function extracts ORIGINAL tl name from given php class name. @@ -924,39 +924,6 @@ inline void tl_debug(const char *s __attribute__((unused)), int n __attribute__( /* {{{ Interface functions */ -// returns 0 if no typedStore was found, otherwise returns allocated ZVAL with fetcher instance -bool store_function2(VK_ZVAL_API_P arr, zval *fetcher) { - ADD_CNT(store_function2) - START_TIMER(store_function2) - assert(arr); - if (Z_TYPE_P(arr) != IS_OBJECT) { - END_TIMER(store_function2) - return false; - } - vk_zend_call_known_instance_method(arr, "typedStore", strlen("typedStore"), fetcher, 0, NULL); - if (EG(exception)) { - // This behavior is consistent with old code, in this case, query_one will return qid 0 - fprintf(stderr, "typedStore exception\n"); - _zend_object* old_exception = EG(exception); - EG(exception) = NULL; - OBJ_RELEASE(old_exception); - END_TIMER(store_function2) - return false; - } - if (Z_TYPE_P(fetcher) != IS_OBJECT) { - // returned null or function not found (undef) or function returned something unexpected - if (Z_TYPE_P(fetcher) != IS_NULL) { - fprintf(stderr, "typedStore fetcher unexpected type is %d\n", Z_TYPE_P(fetcher)); - } - END_TIMER(store_function2) - return false; - } - // when using fetcher, tl_current_function_name will not be accessed. But we set it anyway in case we forgot something. - tl_current_function_name = "typedStore"; - END_TIMER(store_function2) - return true; -} - struct tl_tree *store_function(VK_ZVAL_API_P arr) { ADD_CNT(store_function) START_TIMER(store_function) @@ -1067,7 +1034,7 @@ struct tl_tree *store_function(VK_ZVAL_API_P arr) { return reinterpret_cast(res); } -zval *fetch_function(struct tl_tree *T) { +zval **fetch_function(struct tl_tree *T) { ADD_CNT(fetch_function) START_TIMER(fetch_function) #ifdef VLOG @@ -1090,10 +1057,10 @@ zval *fetch_function(struct tl_tree *T) { vkext_rpc::RpcError rpc_error; rpc_error.try_fetch(); if (rpc_error.error.has_value()) { - zval *ret = make_query_result_or_error(NULL, rpc_error.error.value(), rpc_error.header.has_value() ? &rpc_error.header.value() : nullptr, rpc_error.flags); + *_arr = make_query_result_or_error(NULL, rpc_error.error.value(), rpc_error.header.has_value() ? &rpc_error.header.value() : nullptr, rpc_error.flags); DEC_REF (T); END_TIMER(fetch_function) - return ret; + return _arr; } tl_parse_restore_pos(pos); @@ -1111,55 +1078,28 @@ zval *fetch_function(struct tl_tree *T) { VK_ALLOC_INIT_ZVAL(*_arr); ZVAL_BOOL (*_arr, 1); } - return *_arr; + return _arr; } else { if (*_arr) { zval_dtor (*_arr); } *_arr = make_query_result_or_error(NULL, {TL_ERROR_RESPONSE_SYNTAX, "Can't parse response"}); - return *_arr; + return _arr; } } void _extra_dec_ref(struct rpc_query *q) { - if (!q->extra_free) { - return; - } - q->extra_free = 0; - total_tl_working--; if (q->extra) { - DEC_REF (q->extra); - q->extra = 0; + total_tl_working--; } - zval_ptr_dtor(&q->fetcher); + DEC_REF (q->extra); + q->extra = 0; + q->extra_free = 0; } struct rpc_query *vk_rpc_tl_query_one_impl(struct rpc_connection *c, double timeout, VK_ZVAL_API_P arr, int ignore_answer) { do_rpc_clean(); START_TIMER (tmp); - zval fetcher; - ZVAL_NULL(&fetcher); - bool fetcher_found = store_function2(arr, &fetcher); - END_TIMER (tmp); - if (fetcher_found) { - struct rpc_query *q; - if (!(q = do_rpc_send_noflush(c, timeout, ignore_answer))) { - zval_ptr_dtor(&fetcher); - vkext_error(VKEXT_ERROR_NETWORK, "Can't send packet"); - return 0; - } - if (q == (struct rpc_query *)1) { // answer is ignored - assert (ignore_answer); - zval_ptr_dtor(&fetcher); - return q; - } - assert (!ignore_answer); - ZVAL_COPY_VALUE(&q->fetcher, &fetcher); - q->extra_free = _extra_dec_ref; - total_tl_working++; - return q; - } - START_TIMER (tmp); void *res = store_function(arr); END_TIMER (tmp); if (!res) { @@ -1178,23 +1118,15 @@ struct rpc_query *vk_rpc_tl_query_one_impl(struct rpc_connection *c, double time } assert (!ignore_answer); q->extra = res; - ZVAL_NULL(&q->fetcher); q->extra_free = _extra_dec_ref; total_tl_working++; return q; } -zval *fetch_function2(zval *fetcher); - -zval *vk_rpc_tl_query_result_one_impl(struct tl_tree *T, zval *fetcher) { +zval **vk_rpc_tl_query_result_one_impl(struct tl_tree *T) { tl_parse_init(); START_TIMER (tmp); - zval *r = NULL; - if (T) { - r = fetch_function(T); - }else{ - r = fetch_function2(fetcher); - } + zval **r = fetch_function(T); //fprintf(stderr, "~~~~ after fetch:\n"); //php_debug_zval_dump(*r, 1); END_TIMER (tmp); @@ -1420,80 +1352,9 @@ static zval *convert_rpc_extra_header_to_php_repr(const vkext_rpc::tl::RpcReqRes return res; } -zval *fetch_function2(zval *fetcher) { - ADD_CNT(fetch_function2) - START_TIMER(fetch_function2) - - assert(fetcher); - assert(Z_TYPE_P(fetcher) == IS_OBJECT); - - vkext_rpc::RpcError rpc_error; - rpc_error.try_fetch(); - if (rpc_error.error.has_value()) { - zval *ret = make_query_result_or_error(NULL, rpc_error.error.value(), rpc_error.header.has_value() ? &rpc_error.header.value() : nullptr, rpc_error.flags); - END_TIMER(fetch_function2) - return ret; - } - - zval* return_value; - VK_ALLOC_INIT_ZVAL(return_value); - ZVAL_UNDEF(return_value); - vk_zend_call_known_instance_method(fetcher, "typedFetch", strlen("typedFetch"), return_value, 0, NULL); - if (EG(exception)) { - efree(return_value); // it is UNDEF - - _zend_object * old_exception = EG(exception); - EG(exception) = NULL; - - zval exception_zval; - ZVAL_OBJ(&exception_zval, old_exception); - - zval *message; - VK_ALLOC_INIT_ZVAL(message); - ZVAL_UNDEF(message); - vk_zend_call_known_instance_method(&exception_zval, "getMessage", strlen("getMessage"), message, 0, NULL); - // fprintf(stderr, "getMessage after call %d\n", Z_TYPE(message)); - assert(Z_TYPE_P(message) == IS_STRING); - - OBJ_RELEASE(old_exception); - - zval *_err = create_php_instance(reqResult_error_class_name); - - vk_zend_update_public_property_nod(_err, "error", message); - - // vk_zend_update_public_property_string(_err, "error", "hren"); - vk_zend_update_public_property_long(_err, "error_code", -1000); - END_TIMER(fetch_function2) - return _err; - } - // TODO - will remove later when everything works - // fprintf(stderr, "typedFetch after call %d\n", Z_TYPE_P(return_value)); - if (Z_TYPE_P(return_value) != IS_OBJECT) { // should be never, but that is user code - zval *_err = create_php_instance(reqResult_error_class_name); - vk_zend_update_public_property_string(_err, "error", "fetcher->typedFetch() did not return object, as expected"); - vk_zend_update_public_property_long(_err, "error_code", -1000); - END_TIMER(fetch_function2) - return _err; - } - if (rpc_error.header.has_value()) { - zval *wrapped_err = create_php_instance(reqResult_header_class_name); - zval *header_php_repr = convert_rpc_extra_header_to_php_repr(rpc_error.header.value()); - - set_field_int(&wrapped_err, rpc_error.flags, "flags", -1); - set_field(&wrapped_err, header_php_repr, "extra", -1); - set_field(&wrapped_err, return_value, "result", -1); - END_TIMER(fetch_function2) - return wrapped_err; - } - zval *wrapped_err = create_php_instance(reqResult_underscore_class_name); - set_field(&wrapped_err, return_value, "result", -1); - END_TIMER(fetch_function2) - return wrapped_err; -} - -static zval *make_query_result_or_error(zval *r, const vkext_rpc::tl::RpcReqError &error, const vkext_rpc::tl::RpcReqResultExtra *header, int extra_flags) { +static zval *make_query_result_or_error(zval **r, const vkext_rpc::tl::RpcReqError &error, const vkext_rpc::tl::RpcReqResultExtra *header, int extra_flags) { if (r) { - return r; + return *r; } zval *_err; switch (typed_mode) { @@ -1543,22 +1404,13 @@ void vk_rpc_tl_query_result_impl(struct rpc_queue *Q, double timeout, zval **r) } struct rpc_query *q = rpc_query_get(qid); tl_tree *T = reinterpret_cast(q->extra); - zval fetcher; - ZVAL_COPY(&fetcher, &q->fetcher); tl_current_function_name = q->fun_name; - if (T) { - INC_REF (T); - } + INC_REF (T); if (do_rpc_get_and_parse(qid, timeout - precise_now) < 0) { - // TODO - most likely. leak here (of both T and fetcher). - // But it is difficult to simulate this situation, so - // we decided to keep leak to avoid double delete in case we - // failed to completely understand this code. continue; } - zval *res = make_query_result_or_error(vk_rpc_tl_query_result_one_impl(T, &fetcher), {TL_ERROR_RESPONSE_NOT_FOUND, "Response not found, probably timed out"}); - zval_ptr_dtor(&fetcher); + zval *res = make_query_result_or_error(vk_rpc_tl_query_result_one_impl(T), {TL_ERROR_RESPONSE_NOT_FOUND, "Response not found, probably timed out"}); vk_add_index_zval_nod (*r, qid, res); } } @@ -1589,19 +1441,14 @@ void vk_rpc_tl_query_result_one(INTERNAL_FUNCTION_PARAMETERS) { double timeout = (argc < 2) ? q->timeout : precise_now + parse_zend_double(VK_ZVAL_ARRAY_TO_API_P(z[1])); END_TIMER (parse); auto *T = reinterpret_cast(q->extra); - zval fetcher; - ZVAL_COPY(&fetcher, &q->fetcher); - if (T) { - INC_REF (T); - } + INC_REF (T); if (do_rpc_get_and_parse(qid, timeout - precise_now) < 0) { zval *r = make_query_result_or_error(NULL, {TL_ERROR_RESPONSE_NOT_FOUND, "Response not found, probably timed out"}); RETVAL_ZVAL(r, false, true); efree(r); return; } - zval *r = make_query_result_or_error(vk_rpc_tl_query_result_one_impl(T, &fetcher), {TL_ERROR_RESPONSE_NOT_FOUND, "Response not found, probably timed out"}); - zval_ptr_dtor(&fetcher); + zval *r = make_query_result_or_error(vk_rpc_tl_query_result_one_impl(T), {TL_ERROR_RESPONSE_NOT_FOUND, "Response not found, probably timed out"}); RETVAL_ZVAL(r, false, true); efree(r); } diff --git a/vkext/vkext-rpc.h b/vkext/vkext-rpc.h index 0ac4ad451b..1c16f34beb 100644 --- a/vkext/vkext-rpc.h +++ b/vkext/vkext-rpc.h @@ -113,7 +113,6 @@ struct rpc_query { int answer_len; enum query_status status; void *extra; - zval fetcher; // set if extra == NULL void (*extra_free)(struct rpc_query *); const char *fun_name; }; @@ -304,9 +303,7 @@ struct stats { DECLARE_STAT(store); DECLARE_STAT(fetch); DECLARE_STAT(store_function); - DECLARE_STAT(store_function2); DECLARE_STAT(fetch_function); - DECLARE_STAT(fetch_function2); DECLARE_STAT(crc32); DECLARE_STAT(tree_insert); DECLARE_STAT(total); diff --git a/vkext/vkext.h b/vkext/vkext.h index 834fac75b1..50ebd3ff09 100644 --- a/vkext/vkext.h +++ b/vkext/vkext.h @@ -7,7 +7,7 @@ #include "vkext/vk_zend.h" -#define VKEXT_VERSION "1.02" +#define VKEXT_VERSION "1.02-upload-crash-0" #define VKEXT_NAME "vk_extension"