Skip to content

Commit 1f61dfe

Browse files
committed
ResourceContextManager
1 parent 8b49121 commit 1f61dfe

16 files changed

+283
-47
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
with() boxes resources in ResourceContextManager
3+
--FILE--
4+
<?php
5+
6+
$fd = fopen("php://memory", "r");
7+
with ($fd as $value) {
8+
echo "In with() block\n";
9+
var_dump($value);
10+
}
11+
12+
echo "After with() block\n";
13+
var_dump($fd);
14+
15+
?>
16+
--EXPECTF--
17+
In with() block
18+
resource(%d) of type (stream)
19+
After with() block
20+
resource(%d) of type (Unknown)

Zend/zend_builtin_functions.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@
3131
#include "zend_generators.h"
3232
#include "zend_builtin_functions_arginfo.h"
3333
#include "zend_smart_str.h"
34+
#include "zend_context_managers.h"
3435

3536
/* }}} */
3637

37-
ZEND_API zend_class_entry *zend_ce_context_manager = NULL;
38-
3938
ZEND_MINIT_FUNCTION(core) { /* {{{ */
4039
zend_register_default_classes();
4140

4241
zend_standard_class_def = register_class_stdClass();
43-
zend_ce_context_manager = register_class_ContextManager();
42+
43+
ZEND_MINIT(context_managers)(INIT_FUNC_ARGS_PASSTHRU);
4444

4545
return SUCCESS;
4646
}

Zend/zend_builtin_functions.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "zend_types.h"
2424

2525
typedef struct _zval_struct zval;
26-
extern ZEND_API zend_class_entry *zend_ce_context_manager;
2726

2827
zend_result zend_startup_builtin_functions(void);
2928

Zend/zend_builtin_functions.stub.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ class stdClass
77
{
88
}
99

10-
interface ContextManager
11-
{
12-
public function enterContext(): mixed;
13-
14-
public function exitContext(?\Throwable $e = null): ?bool;
15-
}
16-
1710
/** @refcount 1 */
1811
function clone(object $object, array $withProperties = []): object {}
1912

Zend/zend_builtin_functions_arginfo.h

Lines changed: 1 addition & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Zend/zend_context_managers.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Zend Engine |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 2.00 of the Zend license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.zend.com/license/2_00.txt. |
11+
| If you did not receive a copy of the Zend license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| [email protected] so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
*/
16+
17+
#include "zend.h"
18+
#include "zend_list.h"
19+
#include "zend_API.h"
20+
#include "zend_exceptions.h"
21+
#include "zend_context_managers_arginfo.h"
22+
23+
ZEND_API zend_class_entry *zend_ce_context_manager = NULL;
24+
ZEND_API zend_class_entry *zend_ce_resource_context_manager = NULL;
25+
26+
ZEND_MINIT_FUNCTION(context_managers)
27+
{
28+
zend_ce_context_manager = register_class_ContextManager();
29+
zend_ce_resource_context_manager = register_class_ResourceContextManager(zend_ce_context_manager);
30+
31+
return SUCCESS;
32+
}
33+
34+
void zend_resource_context_manager_init(zend_object *obj, zend_resource *res)
35+
{
36+
zval zres;
37+
ZVAL_RES(&zres, res);
38+
39+
// TODO: reuse zend_update_property_num_checked() or similar
40+
zend_update_property(obj->ce, obj, "resource", strlen("resource"), &zres);
41+
}
42+
43+
ZEND_METHOD(ResourceContextManager, __construct)
44+
{
45+
zval *zres;
46+
zend_object *this = Z_OBJ_P(getThis());
47+
48+
ZEND_PARSE_PARAMETERS_START(1, 1);
49+
Z_PARAM_RESOURCE(zres);
50+
ZEND_PARSE_PARAMETERS_END();
51+
52+
zend_resource_context_manager_init(this, Z_RES_P(zres));
53+
}
54+
55+
ZEND_METHOD(ResourceContextManager, enterContext)
56+
{
57+
zend_object *this = Z_OBJ_P(getThis());
58+
59+
ZEND_PARSE_PARAMETERS_NONE();
60+
61+
zval rv;
62+
zval *zres = zend_read_property(this->ce, this, "resource", strlen("resource"), false, &rv);
63+
64+
if (Z_TYPE_P(zres) != IS_RESOURCE) {
65+
zend_throw_error(NULL, "%s object is not initialized", ZSTR_VAL(this->ce->name));
66+
RETURN_THROWS();
67+
}
68+
69+
RETURN_COPY_DEREF(zres);
70+
}
71+
72+
ZEND_METHOD(ResourceContextManager, exitContext)
73+
{
74+
zend_object *this = Z_OBJ_P(getThis());
75+
zend_object *exception;
76+
77+
ZEND_PARSE_PARAMETERS_START(0, 1);
78+
Z_PARAM_OPTIONAL
79+
Z_PARAM_OBJ_OF_CLASS_OR_NULL(exception, zend_ce_throwable);
80+
ZEND_PARSE_PARAMETERS_END();
81+
82+
zval rv;
83+
zval *zres = zend_read_property(this->ce, this, "resource", strlen("resource"), false, &rv);
84+
85+
if (Z_TYPE_P(zres) != IS_RESOURCE) {
86+
zend_throw_error(NULL, "%s object is not initialized", ZSTR_VAL(this->ce->name));
87+
RETURN_THROWS();
88+
}
89+
90+
zend_resource *res = Z_RES_P(zres);
91+
92+
if (res->type == -1) {
93+
return;
94+
}
95+
96+
zend_resource_dtor(res);
97+
98+
/* Do not swallow exception */
99+
RETURN_FALSE;
100+
}

Zend/zend_context_managers.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Zend Engine |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 2.00 of the Zend license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.zend.com/license/2_00.txt. |
11+
| If you did not receive a copy of the Zend license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| [email protected] so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
*/
16+
17+
#ifndef ZEND_CONTEXT_MANAGERS_H
18+
#define ZEND_CONTEXT_MANAGERS_H
19+
20+
#include "zend_API.h"
21+
22+
extern ZEND_API zend_class_entry *zend_ce_context_manager;
23+
extern ZEND_API zend_class_entry *zend_ce_resource_context_manager;
24+
25+
ZEND_MINIT_FUNCTION(context_managers);
26+
27+
void zend_resource_context_manager_init(zend_object *obj, zend_resource *res);
28+
29+
#endif /* ZEND_CONTEXT_MANAGERS_H */
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/** @generate-class-entries */
4+
5+
interface ContextManager
6+
{
7+
public function enterContext(): mixed;
8+
9+
public function exitContext(?\Throwable $e = null): ?bool;
10+
}
11+
12+
final class ResourceContextManager implements ContextManager
13+
{
14+
private readonly mixed $resource;
15+
16+
public function __construct(mixed $resource) {}
17+
18+
public function enterContext(): mixed {}
19+
20+
public function exitContext(?\Throwable $e = null): ?bool {}
21+
}

Zend/zend_context_managers_arginfo.h

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Zend/zend_execute.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#include "zend_call_stack.h"
4646
#include "zend_attributes.h"
4747
#include "Optimizer/zend_func_info.h"
48-
#include "zend_builtin_functions.h"
48+
#include "zend_context_managers.h"
4949

5050
/* Virtual current working directory support */
5151
#include "zend_virtual_cwd.h"

0 commit comments

Comments
 (0)