diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index d95a4d5036800..9ed5342a7df8f 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -303,16 +303,15 @@ static PHP_MINFO_FUNCTION(bz2) /* {{{ Reads up to length bytes from a BZip2 stream, or 1024 bytes if length is not specified */ PHP_FUNCTION(bzread) { - zval *bz; zend_long len = 1024; php_stream *stream; zend_string *data; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &bz, &len)) { - RETURN_THROWS(); - } - - php_stream_from_zval(stream, bz); + ZEND_PARSE_PARAMETERS_START(1, 2) + PHP_Z_PARAM_STREAM(stream) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(len) + ZEND_PARSE_PARAMETERS_END(); if (len < 0) { zend_argument_value_error(2, "must be greater than or equal to 0"); @@ -563,17 +562,14 @@ PHP_FUNCTION(bzdecompress) The central error handling interface, does the work for bzerrno, bzerrstr and bzerror */ static void php_bz2_error(INTERNAL_FUNCTION_PARAMETERS, int opt) { - zval *bzp; /* BZip2 Resource Pointer */ php_stream *stream; const char *errstr; /* Error string */ int errnum; /* Error number */ struct php_bz2_stream_data_t *self; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &bzp) == FAILURE) { - RETURN_THROWS(); - } - - php_stream_from_zval(stream, bzp); + ZEND_PARSE_PARAMETERS_START(1, 1) + PHP_Z_PARAM_STREAM(stream) + ZEND_PARSE_PARAMETERS_END(); if (!php_stream_is(stream, PHP_STREAM_IS_BZIP2)) { zend_argument_type_error(1, "must be a bz2 stream"); diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index 0336f9e953773..17dc94b728eba 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -566,7 +566,7 @@ PHP_FUNCTION(ftp_systype) /* {{{ Retrieves a file from the FTP server and writes it to an open file */ PHP_FUNCTION(ftp_fget) { - zval *z_ftp, *z_file; + zval *z_ftp; ftpbuf_t *ftp; ftptype_t xtype; php_stream *stream; @@ -574,11 +574,16 @@ PHP_FUNCTION(ftp_fget) size_t file_len; zend_long mode=FTPTYPE_IMAGE, resumepos=0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ors|ll", &z_ftp, php_ftp_ce, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(3, 5) + Z_PARAM_OBJECT_OF_CLASS(z_ftp, php_ftp_ce) + PHP_Z_PARAM_STREAM(stream) + Z_PARAM_STRING(file, file_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(mode) + Z_PARAM_LONG(resumepos) + ZEND_PARSE_PARAMETERS_END(); + GET_FTPBUF(ftp, z_ftp); - php_stream_from_res(stream, Z_RES_P(z_file)); XTYPE(xtype, mode); /* ignore autoresume if autoseek is switched off */ @@ -610,7 +615,7 @@ PHP_FUNCTION(ftp_fget) /* {{{ Retrieves a file from the FTP server asynchronly and writes it to an open file */ PHP_FUNCTION(ftp_nb_fget) { - zval *z_ftp, *z_file; + zval *z_ftp; ftpbuf_t *ftp; ftptype_t xtype; php_stream *stream; @@ -618,11 +623,16 @@ PHP_FUNCTION(ftp_nb_fget) size_t file_len; zend_long mode=FTPTYPE_IMAGE, resumepos=0, ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ors|ll", &z_ftp, php_ftp_ce, &z_file, &file, &file_len, &mode, &resumepos) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(3, 5) + Z_PARAM_OBJECT_OF_CLASS(z_ftp, php_ftp_ce) + PHP_Z_PARAM_STREAM(stream) + Z_PARAM_STRING(file, file_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(mode) + Z_PARAM_LONG(resumepos) + ZEND_PARSE_PARAMETERS_END(); + GET_FTPBUF(ftp, z_ftp); - php_stream_from_res(stream, Z_RES_P(z_file)); XTYPE(xtype, mode); /* ignore autoresume if autoseek is switched off */ @@ -848,7 +858,7 @@ PHP_FUNCTION(ftp_nb_continue) /* {{{ Stores a file from an open file to the FTP server */ PHP_FUNCTION(ftp_fput) { - zval *z_ftp, *z_file; + zval *z_ftp; ftpbuf_t *ftp; ftptype_t xtype; size_t remote_len; @@ -856,11 +866,16 @@ PHP_FUNCTION(ftp_fput) php_stream *stream; char *remote; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osr|ll", &z_ftp, php_ftp_ce, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(3, 5) + Z_PARAM_OBJECT_OF_CLASS(z_ftp, php_ftp_ce) + Z_PARAM_STRING(remote, remote_len) + PHP_Z_PARAM_STREAM(stream) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(mode) + Z_PARAM_LONG(startpos) + ZEND_PARSE_PARAMETERS_END(); + GET_FTPBUF(ftp, z_ftp); - php_stream_from_zval(stream, z_file); XTYPE(xtype, mode); /* ignore autoresume if autoseek is switched off */ @@ -895,7 +910,7 @@ PHP_FUNCTION(ftp_fput) /* {{{ Stores a file from an open file to the FTP server nbronly */ PHP_FUNCTION(ftp_nb_fput) { - zval *z_ftp, *z_file; + zval *z_ftp; ftpbuf_t *ftp; ftptype_t xtype; size_t remote_len; @@ -904,11 +919,16 @@ PHP_FUNCTION(ftp_nb_fput) php_stream *stream; char *remote; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Osr|ll", &z_ftp, php_ftp_ce, &remote, &remote_len, &z_file, &mode, &startpos) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(3, 5) + Z_PARAM_OBJECT_OF_CLASS(z_ftp, php_ftp_ce) + Z_PARAM_STRING(remote, remote_len) + PHP_Z_PARAM_STREAM(stream) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(mode) + Z_PARAM_LONG(startpos) + ZEND_PARSE_PARAMETERS_END(); + GET_FTPBUF(ftp, z_ftp); - php_stream_from_res(stream, Z_RES_P(z_file)); XTYPE(xtype, mode); /* ignore autoresume if autoseek is switched off */ diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 5579aeb978e3c..13c345de4dd1c 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -707,18 +707,20 @@ PHP_FUNCTION(hash_update) /* {{{ Pump data into the hashing algorithm from an open stream */ PHP_FUNCTION(hash_update_stream) { - zval *zhash, *zstream; + zend_object *hash_obj; php_hashcontext_object *hash; php_stream *stream = NULL; zend_long length = -1, didread = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Or|l", &zhash, php_hashcontext_ce, &zstream, &length) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_OBJ_OF_CLASS(hash_obj, php_hashcontext_ce) + PHP_Z_PARAM_STREAM(stream) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(length) + ZEND_PARSE_PARAMETERS_END(); - hash = php_hashcontext_from_object(Z_OBJ_P(zhash)); + hash = php_hashcontext_from_object(hash_obj); PHP_HASHCONTEXT_VERIFY(hash); - php_stream_from_zval(stream, zstream); while (length) { char buf[1024]; diff --git a/ext/opcache/jit/ir/ir.c b/ext/opcache/jit/ir/ir.c index a6bb7c993c51b..2721de4a6e006 100644 --- a/ext/opcache/jit/ir/ir.c +++ b/ext/opcache/jit/ir/ir.c @@ -1294,69 +1294,65 @@ void ir_build_def_use_lists(ir_ctx *ctx) void ir_use_list_remove_all(ir_ctx *ctx, ir_ref from, ir_ref ref) { - ir_ref j, n, *p, *q, use; + ir_ref n, *p, *q, use; ir_use_list *use_list; - ir_ref skip = 0; IR_ASSERT(from > 0); use_list = &ctx->use_lists[from]; n = use_list->count; - for (j = 0, p = q = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { + for (p = q = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; - if (use == ref) { - skip++; - } else { + if (use != ref) { if (p != q) { *q = use; } q++; } } - if (skip) { - use_list->count -= skip; + if (p != q) { + use_list->count -= (p - q); do { *q = IR_UNUSED; q++; - } while (--skip); + } while (q != p); } } void ir_use_list_remove_one(ir_ctx *ctx, ir_ref from, ir_ref ref) { - ir_ref j, n, *p; + ir_ref n, *p; ir_use_list *use_list; IR_ASSERT(from > 0); use_list = &ctx->use_lists[from]; n = use_list->count; - j = 0; p = &ctx->use_edges[use_list->refs]; - while (j < n) { + while (n > 0) { if (*p == ref) { use_list->count--; - j++; - while (j < n) { + n--; + while (n > 0) { *p = *(p+1); p++; - j++; + n--; } *p = IR_UNUSED; break; } p++; - j++; + n--; } } void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use) { ir_use_list *use_list; - ir_ref i, n, *p; + ir_ref n, *p; IR_ASSERT(ref > 0); use_list = &ctx->use_lists[ref]; n = use_list->count; - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { if (*p == use) { *p = new_use; break; @@ -1367,12 +1363,12 @@ void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use void ir_use_list_replace_all(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use) { ir_use_list *use_list; - ir_ref i, n, *p; + ir_ref n, *p; IR_ASSERT(ref > 0); use_list = &ctx->use_lists[ref]; n = use_list->count; - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { if (*p == use) { *p = new_use; } diff --git a/ext/opcache/jit/ir/ir_cfg.c b/ext/opcache/jit/ir/ir_cfg.c index 3678867e46c7a..16facae51b1f6 100644 --- a/ext/opcache/jit/ir/ir_cfg.c +++ b/ext/opcache/jit/ir/ir_cfg.c @@ -328,7 +328,7 @@ static void ir_remove_predecessor(ir_ctx *ctx, ir_block *bb, uint32_t from) static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) { - ir_ref i, j, n, k, *p, use; + ir_ref i, j, n, k, *p, *q, use; ir_insn *use_insn; ir_use_list *use_list; ir_bitset life_inputs; @@ -359,7 +359,7 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) use_list = &ctx->use_lists[merge]; if (use_list->count > 1) { n++; - for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) { + for (k = use_list->count, p = q = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) { use = *p; use_insn = &ctx->ir_base[use]; if (use_insn->op == IR_PHI) { @@ -379,8 +379,22 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) for (j = 2; j <= n; j++) { ir_insn_set_op(use_insn, j, IR_UNUSED); } - ir_use_list_remove_all(ctx, merge, use); + continue; + } + + /*compact use list */ + if (p != q){ + *q = use; } + q++; + } + + if (p != q) { + use_list->count -= (p - q); + do { + *q = IR_UNUSED; /* clenu-op the removed tail */ + q++; + } while (p != q); } } } else { @@ -389,7 +403,7 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from) use_list = &ctx->use_lists[merge]; if (use_list->count > 1) { n++; - for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) { + for (k = use_list->count, p = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) { use = *p; use_insn = &ctx->ir_base[use]; if (use_insn->op == IR_PHI) { diff --git a/ext/opcache/jit/ir/ir_check.c b/ext/opcache/jit/ir/ir_check.c index 40a475ae22f99..f12b4776fa1e0 100644 --- a/ext/opcache/jit/ir/ir_check.c +++ b/ext/opcache/jit/ir/ir_check.c @@ -42,11 +42,11 @@ void ir_consistency_check(void) static bool ir_check_use_list(const ir_ctx *ctx, ir_ref from, ir_ref to) { - ir_ref n, j, *p; + ir_ref n, *p; ir_use_list *use_list = &ctx->use_lists[from]; n = use_list->count; - for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { if (*p == to) { return 1; } @@ -304,9 +304,9 @@ bool ir_check(const ir_ctx *ctx) if (ctx->use_lists) { ir_use_list *use_list = &ctx->use_lists[i]; - ir_ref count; + ir_ref count, n = use_list->count; - for (j = 0, p = &ctx->use_edges[use_list->refs]; j < use_list->count; j++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; if (!ir_check_input_list(ctx, i, use)) { fprintf(stderr, "ir_base[%d] is in use list of ir_base[%d]\n", use, i); @@ -347,8 +347,8 @@ bool ir_check(const ir_ctx *ctx) break; default: /* skip data references */ - count = use_list->count; - for (j = 0, p = &ctx->use_edges[use_list->refs]; j < use_list->count; j++, p++) { + count = n = use_list->count; + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; if (!(ir_op_flags[ctx->ir_base[use].op] & IR_OP_FLAG_CONTROL)) { count--; diff --git a/ext/opcache/jit/ir/ir_dump.c b/ext/opcache/jit/ir/ir_dump.c index f9b26c4d2a12a..54fddf50ac066 100644 --- a/ext/opcache/jit/ir/ir_dump.c +++ b/ext/opcache/jit/ir/ir_dump.c @@ -177,7 +177,7 @@ static void ir_dump_dessa_moves(const ir_ctx *ctx, int b, ir_block *bb, FILE *f) use_list = &ctx->use_lists[succ_bb->start]; k = ir_phi_input_number(ctx, succ_bb, b); - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { use_ref = *p; use_insn = &ctx->ir_base[use_ref]; if (use_insn->op == IR_PHI) { diff --git a/ext/opcache/jit/ir/ir_emit.c b/ext/opcache/jit/ir/ir_emit.c index 367dee72963bf..5cf44a51d0f48 100644 --- a/ext/opcache/jit/ir/ir_emit.c +++ b/ext/opcache/jit/ir/ir_emit.c @@ -161,7 +161,7 @@ static ir_reg ir_get_param_reg(const ir_ctx *ctx, ir_ref ref) } #endif - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { use = *p; insn = &ctx->ir_base[use]; if (insn->op == IR_PARAM) { @@ -917,7 +917,7 @@ static void ir_emit_dessa_moves(ir_ctx *ctx, int b, ir_block *bb) copies = alloca(use_list->count * sizeof(ir_dessa_copy)); - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { ir_ref ref = *p; ir_insn *insn = &ctx->ir_base[ref]; diff --git a/ext/opcache/jit/ir/ir_ra.c b/ext/opcache/jit/ir/ir_ra.c index dcc67e0074fa4..0c0e8dec3b47a 100644 --- a/ext/opcache/jit/ir/ir_ra.c +++ b/ext/opcache/jit/ir/ir_ra.c @@ -1901,7 +1901,6 @@ int ir_coalesce(ir_ctx *ctx) qsort(list, count, sizeof(ir_coalesce_block), ir_block_cmp); while (count > 0) { - uint32_t i; count--; b = list[count].b; @@ -1913,7 +1912,7 @@ int ir_coalesce(ir_ctx *ctx) k = ir_phi_input_number(ctx, succ_bb, b); use_list = &ctx->use_lists[succ_bb->start]; n = use_list->count; - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; insn = &ctx->ir_base[use]; if (insn->op == IR_PHI) { @@ -2061,7 +2060,7 @@ int ir_coalesce(ir_ctx *ctx) int ir_compute_dessa_moves(ir_ctx *ctx) { - uint32_t b, i, n; + uint32_t b, n; ir_ref j, k, *p, use; ir_block *bb; ir_use_list *use_list; @@ -2076,7 +2075,7 @@ int ir_compute_dessa_moves(ir_ctx *ctx) if (n > 1) { IR_ASSERT(k == ctx->ir_base[bb->start].inputs_count); k++; - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; insn = &ctx->ir_base[use]; if (insn->op == IR_PHI) { @@ -2136,7 +2135,7 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy) len = ir_bitset_len(ctx->vregs_count + 1); todo = ir_bitset_malloc(ctx->vregs_count + 1); - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { ref = *p; insn = &ctx->ir_base[ref]; if (insn->op == IR_PHI) { @@ -2205,7 +2204,7 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy) ir_mem_free(loc); if (have_constants_or_addresses) { - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { ref = *p; insn = &ctx->ir_base[ref]; if (insn->op == IR_PHI) { diff --git a/ext/opcache/jit/ir/ir_save.c b/ext/opcache/jit/ir/ir_save.c index be9b142c8f324..b12cc267af607 100644 --- a/ext/opcache/jit/ir/ir_save.c +++ b/ext/opcache/jit/ir/ir_save.c @@ -53,7 +53,7 @@ static void ir_save_dessa_moves(const ir_ctx *ctx, int b, ir_block *bb, FILE *f) use_list = &ctx->use_lists[succ_bb->start]; k = ir_phi_input_number(ctx, succ_bb, b); - for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) { + for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) { use_ref = *p; use_insn = &ctx->ir_base[use_ref]; if (use_insn->op == IR_PHI) { diff --git a/ext/opcache/jit/ir/ir_sccp.c b/ext/opcache/jit/ir/ir_sccp.c index 18192d7f1792a..4f364849390a2 100644 --- a/ext/opcache/jit/ir/ir_sccp.c +++ b/ext/opcache/jit/ir/ir_sccp.c @@ -667,7 +667,7 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi use_list = &ctx->use_lists[i]; n = use_list->count; - for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { + for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { use = *p; IR_ASSERT(use > 0); use_insn = &ctx->ir_base[use]; @@ -1048,7 +1048,7 @@ static void ir_sccp_remove_unfeasible_merge_inputs(ir_ctx *ctx, ir_insn *_values n++; use_list = &ctx->use_lists[ref]; if (use_list->count > 1) { - for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) { + for (k = use_list->count, p = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) { use = *p; use_insn = &ctx->ir_base[use]; if (use_insn->op == IR_PHI) { @@ -1715,6 +1715,7 @@ static bool ir_may_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref) case IR_OR: case IR_AND: case IR_XOR: + case IR_SHL: return ctx->use_lists[ref].count == 1 && ir_may_promote_i2i(ctx, type, insn->op1) && ir_may_promote_i2i(ctx, type, insn->op2); @@ -1773,6 +1774,7 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use) case IR_OR: case IR_AND: case IR_XOR: + case IR_SHL: if (insn->op1 == insn->op2) { insn->op2 = insn->op1 = ir_promote_i2i(ctx, type, insn->op1, ref); } else { @@ -2952,6 +2954,14 @@ static ir_ref ir_iter_optimize_condition(ir_ctx *ctx, ir_ref control, ir_ref con { ir_insn *condition_insn = &ctx->ir_base[condition]; + while ((condition_insn->op == IR_BITCAST + || condition_insn->op == IR_ZEXT + || condition_insn->op == IR_SEXT) + && ctx->use_lists[condition].count == 1) { + condition = condition_insn->op1; + condition_insn = &ctx->ir_base[condition]; + } + if (condition_insn->opt == IR_OPT(IR_NOT, IR_BOOL)) { *swap = 1; condition = condition_insn->op1; diff --git a/ext/opcache/jit/ir/ir_x86.dasc b/ext/opcache/jit/ir/ir_x86.dasc index c4f0eae01c004..3b6cf156ad909 100644 --- a/ext/opcache/jit/ir/ir_x86.dasc +++ b/ext/opcache/jit/ir/ir_x86.dasc @@ -1010,6 +1010,7 @@ const char *ir_reg_name(int8_t reg, ir_type type) _(MOD_PWR2) \ _(SDIV_PWR2) \ _(SMOD_PWR2) \ + _(BOOL_NOT) \ _(BOOL_NOT_INT) \ _(ABS_INT) \ _(OP_INT) \ @@ -2223,10 +2224,16 @@ binop_fp: ir_match_fuse_load(ctx, insn->op2, ref); return IR_MOD_INT; case IR_BSWAP: + IR_ASSERT(IR_IS_TYPE_INT(insn->type)); + return IR_OP_INT; case IR_NOT: if (insn->type == IR_BOOL) { - IR_ASSERT(IR_IS_TYPE_INT(ctx->ir_base[insn->op1].type)); // TODO: IR_BOOL_NOT_FP - return IR_BOOL_NOT_INT; + if (ctx->ir_base[insn->op1].type == IR_BOOL) { + return IR_BOOL_NOT; + } else { + IR_ASSERT(IR_IS_TYPE_INT(ctx->ir_base[insn->op1].type)); // TODO: IR_BOOL_NOT_FP + return IR_BOOL_NOT_INT; + } } else { IR_ASSERT(IR_IS_TYPE_INT(insn->type)); return IR_OP_INT; @@ -5054,6 +5061,33 @@ static void ir_emit_abs_int(ir_ctx *ctx, ir_ref def, ir_insn *insn) } } +static void ir_emit_bool_not(ir_ctx *ctx, ir_ref def, ir_insn *insn) +{ + ir_backend_data *data = ctx->data; + dasm_State **Dst = &data->dasm_state; + ir_type type = ctx->ir_base[insn->op1].type; + ir_ref op1 = insn->op1; + ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]); + ir_reg op1_reg = ctx->regs[def][1]; + + IR_ASSERT(def_reg != IR_REG_NONE); + + if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) { + op1_reg = IR_REG_NUM(op1_reg); + ir_emit_load(ctx, type, op1_reg, op1); + } + + if (def_reg != op1_reg) { + | mov Rb(def_reg), Rb(op1_reg) + } + + | xor Rb(def_reg), 1 + + if (IR_REG_SPILLED(ctx->regs[def][0])) { + ir_emit_store(ctx, type, def, def_reg); + } +} + static void ir_emit_bool_not_int(ir_ctx *ctx, ir_ref def, ir_insn *insn) { ir_backend_data *data = ctx->data; @@ -10602,6 +10636,9 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) case IR_ABS_INT: ir_emit_abs_int(ctx, i, insn); break; + case IR_BOOL_NOT: + ir_emit_bool_not(ctx, i, insn); + break; case IR_BOOL_NOT_INT: ir_emit_bool_not_int(ctx, i, insn); break; diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index b1a1dfb49a7ac..036fc5c0572a1 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -6265,22 +6265,19 @@ PHP_FUNCTION(pg_put_copy_end) PHP_FUNCTION(pg_socket_poll) { - zval *z_socket; php_stream *stream; php_socket_t socket; zend_long read, write; zend_long ts = -1; ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_RESOURCE(z_socket) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(read) Z_PARAM_LONG(write) Z_PARAM_OPTIONAL Z_PARAM_LONG(ts) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, z_socket); - if (php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void **)&socket, 0)) { zend_argument_type_error(1, "invalid resource socket"); RETURN_THROWS(); diff --git a/ext/standard/file.c b/ext/standard/file.c index 01f49640e4af6..908aee85a2e74 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -102,10 +102,6 @@ php_file_globals file_globals; /* }}} */ -#define PHP_STREAM_FROM_ZVAL(stream, arg) \ - ZEND_ASSERT(Z_TYPE_P(arg) == IS_RESOURCE); \ - php_stream_from_res(stream, Z_RES_P(arg)); - /* {{{ ZTS-stuff / Globals / Prototypes */ /* sharing globals is *evil* */ @@ -215,19 +211,17 @@ PHPAPI void php_flock_common(php_stream *stream, zend_long operation, /* {{{ Portable file locking */ PHP_FUNCTION(flock) { - zval *res, *wouldblock = NULL; + zval *wouldblock = NULL; php_stream *stream; zend_long operation = 0; ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(operation) Z_PARAM_OPTIONAL Z_PARAM_ZVAL(wouldblock) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - php_flock_common(stream, operation, 2, wouldblock, return_value); } /* }}} */ @@ -756,15 +750,12 @@ PHP_FUNCTION(fopen) /* {{{ Close an open file pointer */ PHPAPI PHP_FUNCTION(fclose) { - zval *res; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) { php_error_docref(NULL, E_WARNING, ZEND_LONG_FMT " is not a valid stream resource", stream->res->handle); RETURN_FALSE; @@ -836,15 +827,12 @@ PHP_FUNCTION(popen) /* {{{ Close a file pointer opened by popen() */ PHP_FUNCTION(pclose) { - zval *res; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - FG(pclose_wait) = 1; zend_list_close(stream->res); FG(pclose_wait) = 0; @@ -855,15 +843,12 @@ PHP_FUNCTION(pclose) /* {{{ Test for end-of-file on a file pointer */ PHPAPI PHP_FUNCTION(feof) { - zval *res; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - if (php_stream_eof(stream)) { RETURN_TRUE; } else { @@ -875,7 +860,6 @@ PHPAPI PHP_FUNCTION(feof) /* {{{ Get a line from file pointer */ PHPAPI PHP_FUNCTION(fgets) { - zval *res; zend_long len = 1024; bool len_is_null = 1; char *buf = NULL; @@ -884,13 +868,11 @@ PHPAPI PHP_FUNCTION(fgets) php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(len, len_is_null) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - if (len_is_null) { /* ask streams to give us a buffer of an appropriate size */ buf = php_stream_get_line(stream, NULL, 0, &line_len); @@ -926,15 +908,12 @@ PHPAPI PHP_FUNCTION(fgets) /* {{{ Get a character from file pointer */ PHPAPI PHP_FUNCTION(fgetc) { - zval *res; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - int result = php_stream_getc(stream); if (result == EOF) { @@ -989,7 +968,6 @@ PHP_FUNCTION(fscanf) /* {{{ Binary-safe file write */ PHPAPI PHP_FUNCTION(fwrite) { - zval *res; char *input; size_t inputlen; ssize_t ret; @@ -999,7 +977,7 @@ PHPAPI PHP_FUNCTION(fwrite) php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_STRING(input, inputlen) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(maxlen, maxlen_is_null) @@ -1017,8 +995,6 @@ PHPAPI PHP_FUNCTION(fwrite) RETURN_LONG(0); } - PHP_STREAM_FROM_ZVAL(stream, res); - ret = php_stream_write(stream, input, num_bytes); if (ret < 0) { RETURN_FALSE; @@ -1031,16 +1007,13 @@ PHPAPI PHP_FUNCTION(fwrite) /* {{{ Flushes output */ PHPAPI PHP_FUNCTION(fflush) { - zval *res; int ret; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - ret = php_stream_flush(stream); if (ret) { RETURN_FALSE; @@ -1052,15 +1025,12 @@ PHPAPI PHP_FUNCTION(fflush) /* {{{ Rewind the position of a file pointer */ PHPAPI PHP_FUNCTION(rewind) { - zval *res; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - if (-1 == php_stream_rewind(stream)) { RETURN_FALSE; } @@ -1071,16 +1041,13 @@ PHPAPI PHP_FUNCTION(rewind) /* {{{ Get file pointer's read/write position */ PHPAPI PHP_FUNCTION(ftell) { - zval *res; zend_long ret; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - ret = php_stream_tell(stream); if (ret == -1) { RETURN_FALSE; @@ -1092,19 +1059,16 @@ PHPAPI PHP_FUNCTION(ftell) /* {{{ Seek on a file pointer */ PHPAPI PHP_FUNCTION(fseek) { - zval *res; zend_long offset, whence = SEEK_SET; php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(offset) Z_PARAM_OPTIONAL Z_PARAM_LONG(whence) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - RETURN_LONG(php_stream_seek(stream, offset, (int) whence)); } /* }}} */ @@ -1215,16 +1179,13 @@ PHP_FUNCTION(umask) /* {{{ Output all remaining data from a file pointer */ PHPAPI PHP_FUNCTION(fpassthru) { - zval *res; size_t size; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - size = php_stream_passthru(stream); RETURN_LONG(size); } @@ -1303,15 +1264,12 @@ PHP_FUNCTION(unlink) PHP_FUNCTION(fsync) { - zval *res; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - if (!php_stream_sync_supported(stream)) { php_error_docref(NULL, E_WARNING, "Can't fsync this stream!"); RETURN_FALSE; @@ -1322,15 +1280,12 @@ PHP_FUNCTION(fsync) PHP_FUNCTION(fdatasync) { - zval *res; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - if (!php_stream_sync_supported(stream)) { php_error_docref(NULL, E_WARNING, "Can't fsync this stream!"); RETURN_FALSE; @@ -1342,12 +1297,11 @@ PHP_FUNCTION(fdatasync) /* {{{ Truncate file to 'size' length */ PHP_FUNCTION(ftruncate) { - zval *fp; zend_long size; php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(fp) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(size) ZEND_PARSE_PARAMETERS_END(); @@ -1356,8 +1310,6 @@ PHP_FUNCTION(ftruncate) RETURN_THROWS(); } - PHP_STREAM_FROM_ZVAL(stream, fp); - if (!php_stream_truncate_supported(stream)) { php_error_docref(NULL, E_WARNING, "Can't truncate this stream!"); RETURN_FALSE; @@ -1441,15 +1393,12 @@ PHPAPI void php_fstat(php_stream *stream, zval *return_value) /* {{{ Stat() on a filehandle */ PHP_FUNCTION(fstat) { - zval *fp; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(fp) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, fp); - php_fstat(stream, return_value); } /* }}} */ @@ -1588,18 +1537,15 @@ PHPAPI zend_result php_copy_file_ctx(const char *src, const char *dest, int src_ /* {{{ Binary-safe file read */ PHPAPI PHP_FUNCTION(fread) { - zval *res; zend_long len; php_stream *stream; zend_string *str; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(res) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(len) ZEND_PARSE_PARAMETERS_END(); - PHP_STREAM_FROM_ZVAL(stream, res); - if (len <= 0) { zend_argument_value_error(2, "must be greater than 0"); RETURN_THROWS(); @@ -1683,7 +1629,7 @@ PHP_FUNCTION(fputcsv) char delimiter = ','; /* allow this to be set as parameter */ char enclosure = '"'; /* allow this to be set as parameter */ php_stream *stream; - zval *fp = NULL, *fields = NULL; + zval *fields = NULL; ssize_t ret; char *delimiter_str = NULL, *enclosure_str = NULL; zend_string *escape_str = NULL; @@ -1691,7 +1637,7 @@ PHP_FUNCTION(fputcsv) zend_string *eol_str = NULL; ZEND_PARSE_PARAMETERS_START(2, 6) - Z_PARAM_RESOURCE(fp) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_ARRAY(fields) Z_PARAM_OPTIONAL Z_PARAM_STRING(delimiter_str, delimiter_str_len) @@ -1725,8 +1671,6 @@ PHP_FUNCTION(fputcsv) RETURN_THROWS(); } - PHP_STREAM_FROM_ZVAL(stream, fp); - ret = php_fputcsv(stream, fields, delimiter, enclosure, escape_char, eol_str); if (ret < 0) { RETURN_FALSE; @@ -1811,7 +1755,6 @@ PHP_FUNCTION(fgetcsv) char *buf; php_stream *stream; - zval *fd; bool len_is_null = 1; char *delimiter_str = NULL; size_t delimiter_str_len = 0; @@ -1820,7 +1763,7 @@ PHP_FUNCTION(fgetcsv) zend_string *escape_str = NULL; ZEND_PARSE_PARAMETERS_START(1, 5) - Z_PARAM_RESOURCE(fd) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(len, len_is_null) Z_PARAM_STRING(delimiter_str, delimiter_str_len) @@ -1861,8 +1804,6 @@ PHP_FUNCTION(fgetcsv) RETURN_THROWS(); } - PHP_STREAM_FROM_ZVAL(stream, fd); - if (len < 0) { if ((buf = php_stream_get_line(stream, NULL, 0, &buf_len)) == NULL) { RETURN_FALSE; diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 8d8c09f443c04..9471ad3c7ba23 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -860,18 +860,16 @@ PHP_FUNCTION(fprintf) php_stream *stream; char *format; size_t format_len; - zval *arg1, *args; - int argc; + zval *args = NULL; + int argc = 0; zend_string *result; ZEND_PARSE_PARAMETERS_START(2, -1) - Z_PARAM_RESOURCE(arg1) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_STRING(format, format_len) Z_PARAM_VARIADIC('*', args, argc) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, arg1); - result = php_formatted_print(format, format_len, args, argc, 2); if (result == NULL) { RETURN_THROWS(); @@ -890,19 +888,17 @@ PHP_FUNCTION(vfprintf) php_stream *stream; char *format; size_t format_len; - zval *arg1, *args; + zval *args; zend_array *array; int argc; zend_string *result; ZEND_PARSE_PARAMETERS_START(3, 3) - Z_PARAM_RESOURCE(arg1) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_STRING(format, format_len) Z_PARAM_ARRAY_HT(array) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, arg1); - args = php_formatted_print_get_array(array, &argc); result = php_formatted_print(format, format_len, args, argc, -1); diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 4f9a7106c01c1..818a645086b05 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -265,11 +265,10 @@ PHP_FUNCTION(stream_socket_accept) php_timeout_ull conv; struct timeval tv; php_stream *stream = NULL, *clistream = NULL; - zval *zstream; zend_string *errstr = NULL; ZEND_PARSE_PARAMETERS_START(1, 3) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_OPTIONAL Z_PARAM_DOUBLE_OR_NULL(timeout, timeout_is_null) Z_PARAM_ZVAL(zpeername) @@ -282,8 +281,6 @@ PHP_FUNCTION(stream_socket_accept) RETURN_THROWS(); } - php_stream_from_zval(stream, zstream); - /* prepare the timeout value for use */ struct timeval *tv_pointer; if (timeout < 0.0 || timeout >= (double) PHP_TIMEOUT_ULL_MAX / 1000000.0) { @@ -328,17 +325,14 @@ PHP_FUNCTION(stream_socket_accept) PHP_FUNCTION(stream_socket_get_name) { php_stream *stream; - zval *zstream; bool want_peer; zend_string *name = NULL; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_BOOL(want_peer) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zstream); - if (0 != php_stream_xport_get_name(stream, want_peer, &name, NULL, NULL @@ -359,7 +353,6 @@ PHP_FUNCTION(stream_socket_get_name) PHP_FUNCTION(stream_socket_sendto) { php_stream *stream; - zval *zstream; zend_long flags = 0; char *data, *target_addr = NULL; size_t datalen, target_addr_len = 0; @@ -367,13 +360,12 @@ PHP_FUNCTION(stream_socket_sendto) socklen_t sl = 0; ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_STRING(data, datalen) Z_PARAM_OPTIONAL Z_PARAM_LONG(flags) Z_PARAM_STRING(target_addr, target_addr_len) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zstream); if (target_addr_len) { /* parse the address */ @@ -391,7 +383,7 @@ PHP_FUNCTION(stream_socket_sendto) PHP_FUNCTION(stream_socket_recvfrom) { php_stream *stream; - zval *zstream, *zremote = NULL; + zval *zremote = NULL; zend_string *remote_addr = NULL; zend_long to_read = 0; zend_string *read_buf; @@ -399,15 +391,13 @@ PHP_FUNCTION(stream_socket_recvfrom) int recvd; ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(to_read) Z_PARAM_OPTIONAL Z_PARAM_LONG(flags) Z_PARAM_ZVAL(zremote) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zstream); - if (zremote) { ZEND_TRY_ASSIGN_REF_NULL(zremote); } @@ -441,13 +431,12 @@ PHP_FUNCTION(stream_socket_recvfrom) PHP_FUNCTION(stream_get_contents) { php_stream *stream; - zval *zsrc; zend_long maxlen, desiredpos = -1L; bool maxlen_is_null = 1; zend_string *contents; ZEND_PARSE_PARAMETERS_START(1, 3) - Z_PARAM_RESOURCE(zsrc) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(maxlen, maxlen_is_null) Z_PARAM_LONG(desiredpos) @@ -460,8 +449,6 @@ PHP_FUNCTION(stream_get_contents) RETURN_THROWS(); } - php_stream_from_zval(stream, zsrc); - if (desiredpos >= 0) { int seek_res = 0; zend_off_t position; @@ -494,15 +481,14 @@ PHP_FUNCTION(stream_get_contents) PHP_FUNCTION(stream_copy_to_stream) { php_stream *src, *dest; - zval *zsrc, *zdest; zend_long maxlen, pos = 0; bool maxlen_is_null = 1; size_t len; int ret; ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_RESOURCE(zsrc) - Z_PARAM_RESOURCE(zdest) + PHP_Z_PARAM_STREAM(src) + PHP_Z_PARAM_STREAM(dest) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(maxlen, maxlen_is_null) Z_PARAM_LONG(pos) @@ -512,9 +498,6 @@ PHP_FUNCTION(stream_copy_to_stream) maxlen = PHP_STREAM_COPY_ALL; } - php_stream_from_zval(src, zsrc); - php_stream_from_zval(dest, zdest); - if (pos > 0 && php_stream_seek(src, pos, SEEK_SET) < 0) { php_error_docref(NULL, E_WARNING, "Failed to seek to position " ZEND_LONG_FMT " in the stream", pos); RETURN_FALSE; @@ -532,15 +515,12 @@ PHP_FUNCTION(stream_copy_to_stream) /* {{{ Retrieves header/meta data from streams/file pointers */ PHP_FUNCTION(stream_get_meta_data) { - zval *zstream; php_stream *stream; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zstream); - array_init(return_value); if (!php_stream_populate_meta_data(stream, return_value)) { @@ -1235,7 +1215,6 @@ PHP_FUNCTION(stream_context_create) /* {{{ streams filter functions */ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) { - zval *zstream; php_stream *stream; char *filtername; size_t filternamelen; @@ -1245,15 +1224,13 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) int ret; ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_STRING(filtername, filternamelen) Z_PARAM_OPTIONAL Z_PARAM_LONG(read_write) Z_PARAM_ZVAL(filterparams) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zstream); - if ((read_write & PHP_STREAM_FILTER_ALL) == 0) { /* Chain not specified. * Examine stream->mode to determine which filters are needed @@ -1358,12 +1335,11 @@ PHP_FUNCTION(stream_get_line) char *str = NULL; size_t str_len = 0; zend_long max_length; - zval *zstream; zend_string *buf; php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(max_length) Z_PARAM_OPTIONAL Z_PARAM_STRING(str, str_len) @@ -1377,8 +1353,6 @@ PHP_FUNCTION(stream_get_line) max_length = PHP_SOCK_CHUNK_SIZE; } - php_stream_from_zval(stream, zstream); - if ((buf = php_stream_get_record(stream, max_length, str, str_len))) { RETURN_STR(buf); } else { @@ -1391,17 +1365,14 @@ PHP_FUNCTION(stream_get_line) /* {{{ Set blocking/non-blocking mode on a socket or stream */ PHP_FUNCTION(stream_set_blocking) { - zval *zstream; bool block; php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_BOOL(block) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zstream); - if (php_stream_set_option(stream, PHP_STREAM_OPTION_BLOCKING, block, NULL) == -1) { RETURN_FALSE; } @@ -1415,21 +1386,18 @@ PHP_FUNCTION(stream_set_blocking) #if defined(HAVE_SYS_TIME_H) || defined(PHP_WIN32) PHP_FUNCTION(stream_set_timeout) { - zval *socket; zend_long seconds, microseconds = 0; struct timeval t; php_stream *stream; int argc = ZEND_NUM_ARGS(); ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(socket) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(seconds) Z_PARAM_OPTIONAL Z_PARAM_LONG(microseconds) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, socket); - #ifdef PHP_WIN32 t.tv_sec = (long)seconds; @@ -1462,19 +1430,16 @@ PHP_FUNCTION(stream_set_timeout) /* {{{ Set file write buffer */ PHP_FUNCTION(stream_set_write_buffer) { - zval *arg1; int ret; zend_long arg2; size_t buff; php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(arg1) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(arg2) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, arg1); - buff = arg2; /* if buff is 0 then set to non-buffered */ @@ -1493,11 +1458,10 @@ PHP_FUNCTION(stream_set_chunk_size) { int ret; zend_long csize; - zval *zstream; php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(csize) ZEND_PARSE_PARAMETERS_END(); @@ -1514,8 +1478,6 @@ PHP_FUNCTION(stream_set_chunk_size) RETURN_THROWS(); } - php_stream_from_zval(stream, zstream); - ret = php_stream_set_option(stream, PHP_STREAM_OPTION_SET_CHUNK_SIZE, (int)csize, NULL); RETURN_LONG(ret > 0 ? (zend_long)ret : (zend_long)EOF); @@ -1525,19 +1487,16 @@ PHP_FUNCTION(stream_set_chunk_size) /* {{{ Set file read buffer */ PHP_FUNCTION(stream_set_read_buffer) { - zval *arg1; int ret; zend_long arg2; size_t buff; php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(arg1) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(arg2) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, arg1); - buff = arg2; /* if buff is 0 then set to non-buffered */ @@ -1555,21 +1514,18 @@ PHP_FUNCTION(stream_set_read_buffer) PHP_FUNCTION(stream_socket_enable_crypto) { zend_long cryptokind = 0; - zval *zstream, *zsessstream = NULL; php_stream *stream, *sessstream = NULL; bool enable, cryptokindnull = 1; int ret; ZEND_PARSE_PARAMETERS_START(2, 4) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_BOOL(enable) Z_PARAM_OPTIONAL Z_PARAM_LONG_OR_NULL(cryptokind, cryptokindnull) - Z_PARAM_RESOURCE_OR_NULL(zsessstream) + PHP_Z_PARAM_STREAM_OR_NULL(sessstream) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zstream); - if (enable) { if (cryptokindnull) { zval *val; @@ -1582,10 +1538,6 @@ PHP_FUNCTION(stream_socket_enable_crypto) cryptokind = Z_LVAL_P(val); } - if (zsessstream) { - php_stream_from_zval(sessstream, zsessstream); - } - if (php_stream_xport_crypto_setup(stream, cryptokind, sessstream) < 0) { RETURN_FALSE; } @@ -1658,14 +1610,11 @@ PHP_FUNCTION(stream_is_local) PHP_FUNCTION(stream_supports_lock) { php_stream *stream; - zval *zsrc; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(zsrc) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zsrc); - if (!php_stream_supports_lock(stream)) { RETURN_FALSE; } @@ -1676,16 +1625,13 @@ PHP_FUNCTION(stream_supports_lock) /* {{{ Check if a stream is a TTY. */ PHP_FUNCTION(stream_isatty) { - zval *zsrc; php_stream *stream; php_socket_t fileno; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(zsrc) + PHP_Z_PARAM_STREAM(stream) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zsrc); - /* get the fd. * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag when casting. * It is only used here so that the buffered data warning is not displayed. @@ -1718,19 +1664,16 @@ PHP_FUNCTION(stream_isatty) */ PHP_FUNCTION(sapi_windows_vt100_support) { - zval *zsrc; php_stream *stream; bool enable, enable_is_null = 1; zend_long fileno; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_RESOURCE(zsrc) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_OPTIONAL Z_PARAM_BOOL_OR_NULL(enable, enable_is_null) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zsrc); - /* get the fd. * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag when casting. * It is only used here so that the buffered data warning is not displayed. @@ -1785,11 +1728,10 @@ PHP_FUNCTION(sapi_windows_vt100_support) PHP_FUNCTION(stream_socket_shutdown) { zend_long how; - zval *zstream; php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_LONG(how) ZEND_PARSE_PARAMETERS_END(); @@ -1800,8 +1742,6 @@ PHP_FUNCTION(stream_socket_shutdown) RETURN_THROWS(); } - php_stream_from_zval(stream, zstream); - RETURN_BOOL(php_stream_xport_shutdown(stream, (stream_shutdown_t)how) == 0); } /* }}} */ diff --git a/ext/standard/tests/file/fwrite.phpt b/ext/standard/tests/file/fwrite.phpt index 90e158d048a6c..1494ea7a0f5e8 100644 --- a/ext/standard/tests/file/fwrite.phpt +++ b/ext/standard/tests/file/fwrite.phpt @@ -17,13 +17,21 @@ var_dump(fwrite($fp, "data", -1)); var_dump(fwrite($fp, "data", 100000)); fclose($fp); -var_dump(fwrite($fp, "data", -1)); +try { + var_dump(fwrite($fp, "data", -1)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} var_dump(file_get_contents($filename)); -@unlink($filename); echo "Done\n"; ?> +--CLEAN-- + --EXPECTF-- int(0) @@ -31,6 +39,6 @@ Notice: fwrite(): Write of 4 bytes failed with errno=9 Bad file descriptor in %s bool(false) int(0) int(4) -int(0) +TypeError: fwrite(): supplied resource is not a valid stream resource string(4) "data" Done diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index 2168fbce0af34..88facf1e137f2 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -439,7 +439,7 @@ PHP_FUNCTION(stream_bucket_append) /* {{{ Create a new bucket for use on the current stream */ PHP_FUNCTION(stream_bucket_new) { - zval *zstream, zbucket; + zval zbucket; php_stream *stream; char *buffer; char *pbuffer; @@ -447,11 +447,10 @@ PHP_FUNCTION(stream_bucket_new) php_stream_bucket *bucket; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_ZVAL(zstream) + PHP_Z_PARAM_STREAM(stream) Z_PARAM_STRING(buffer, buffer_len) ZEND_PARSE_PARAMETERS_END(); - php_stream_from_zval(stream, zstream); pbuffer = pemalloc(buffer_len, php_stream_is_persistent(stream)); memcpy(pbuffer, buffer, buffer_len); diff --git a/main/php_streams.h b/main/php_streams.h index 33b14ff4eb3df..80cb96951ee14 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -286,6 +286,35 @@ END_EXTERN_C() #define php_stream_from_zval_no_verify(xstr, pzval) (xstr) = (php_stream*)zend_fetch_resource2_ex((pzval), "stream", php_file_le_stream(), php_file_le_pstream()) BEGIN_EXTERN_C() + +static zend_always_inline bool php_stream_zend_parse_arg_into_stream(zval *arg, php_stream **destination_stream_ptr, bool check_null) +{ + if (EXPECTED(Z_TYPE_P(arg) == IS_RESOURCE)) { + *destination_stream_ptr = (php_stream*)zend_fetch_resource2(Z_RES_P(arg), "stream", php_file_le_stream(), php_file_le_pstream()); + if (UNEXPECTED(*destination_stream_ptr == NULL)) { + return false; + } + } else if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) { + *destination_stream_ptr = NULL; + } else { + return false; + } + return true; +} + +#define PHP_Z_PARAM_STREAM_EX(destination_stream_ptr, check_null) \ + Z_PARAM_PROLOGUE(0, 0); \ + if (UNEXPECTED(!php_stream_zend_parse_arg_into_stream(_arg, &destination_stream_ptr, check_null))) { \ + _error_code = ZPP_ERROR_FAILURE; \ + if (!EG(exception)) { \ + _expected_type = check_null ? Z_EXPECTED_RESOURCE_OR_NULL : Z_EXPECTED_RESOURCE; \ + _error_code = ZPP_ERROR_WRONG_ARG; \ + } \ + break; \ + } +#define PHP_Z_PARAM_STREAM(dest) PHP_Z_PARAM_STREAM_EX(dest, false) +#define PHP_Z_PARAM_STREAM_OR_NULL(dest) PHP_Z_PARAM_STREAM_EX(dest, true) + PHPAPI php_stream *php_stream_encloses(php_stream *enclosing, php_stream *enclosed); #define php_stream_free_enclosed(stream_enclosed, close_options) _php_stream_free_enclosed((stream_enclosed), (close_options)) PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options);