Skip to content

Commit f79f5d2

Browse files
committed
Add support for declaring class entries in stubs
1 parent 497a0e5 commit f79f5d2

34 files changed

+927
-179
lines changed

Zend/zend_exceptions.c

Lines changed: 15 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -740,87 +740,49 @@ ZEND_METHOD(Exception, __toString)
740740
}
741741
/* }}} */
742742

743-
static void declare_exception_properties(zend_class_entry *ce)
744-
{
745-
zval val;
746-
747-
zend_declare_property_string(ce, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED);
748-
zend_declare_property_string(ce, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE);
749-
zend_declare_property_long(ce, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED);
750-
zend_declare_property_null(ce, "file", sizeof("file")-1, ZEND_ACC_PROTECTED);
751-
zend_declare_property_null(ce, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
752-
753-
ZVAL_EMPTY_ARRAY(&val);
754-
zend_declare_typed_property(
755-
ce, ZSTR_KNOWN(ZEND_STR_TRACE), &val, ZEND_ACC_PRIVATE, NULL,
756-
(zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY));
757-
758-
ZVAL_NULL(&val);
759-
zend_declare_typed_property(
760-
ce, ZSTR_KNOWN(ZEND_STR_PREVIOUS), &val, ZEND_ACC_PRIVATE, NULL,
761-
(zend_type) ZEND_TYPE_INIT_CE(zend_ce_throwable, /* allow_null */ 1, 0));
762-
}
763-
764743
void zend_register_default_exception(void) /* {{{ */
765744
{
766-
zend_class_entry ce;
767-
768-
REGISTER_MAGIC_INTERFACE(throwable, Throwable);
769-
zend_class_implements(zend_ce_throwable, 1, zend_ce_stringable);
745+
register_class_Throwable(zend_ce_throwable, zend_ce_stringable);
746+
zend_ce_throwable->interface_gets_implemented = zend_implement_throwable;
770747

771748
memcpy(&default_exception_handlers, &std_object_handlers, sizeof(zend_object_handlers));
772749
default_exception_handlers.clone_obj = NULL;
773750

774-
INIT_CLASS_ENTRY(ce, "Exception", class_Exception_methods);
775-
zend_ce_exception = zend_register_internal_class_ex(&ce, NULL);
751+
register_class_Exception(zend_ce_exception, zend_ce_throwable);
776752
zend_ce_exception->create_object = zend_default_exception_new;
777-
zend_class_implements(zend_ce_exception, 1, zend_ce_throwable);
778-
declare_exception_properties(zend_ce_exception);
779753

780-
INIT_CLASS_ENTRY(ce, "ErrorException", class_ErrorException_methods);
781-
zend_ce_error_exception = zend_register_internal_class_ex(&ce, zend_ce_exception);
754+
register_class_ErrorException(zend_ce_error_exception, zend_ce_exception);
782755
zend_ce_error_exception->create_object = zend_error_exception_new;
783756
zend_declare_property_long(zend_ce_error_exception, "severity", sizeof("severity")-1, E_ERROR, ZEND_ACC_PROTECTED);
784757

785-
INIT_CLASS_ENTRY(ce, "Error", class_Error_methods);
786-
zend_ce_error = zend_register_internal_class_ex(&ce, NULL);
758+
register_class_Error(zend_ce_error, zend_ce_throwable);
787759
zend_ce_error->create_object = zend_default_exception_new;
788-
zend_class_implements(zend_ce_error, 1, zend_ce_throwable);
789-
declare_exception_properties(zend_ce_error);
790760

791-
INIT_CLASS_ENTRY(ce, "CompileError", class_CompileError_methods);
792-
zend_ce_compile_error = zend_register_internal_class_ex(&ce, zend_ce_error);
761+
register_class_CompileError(zend_ce_compile_error, zend_ce_error);
793762
zend_ce_compile_error->create_object = zend_default_exception_new;
794763

795-
INIT_CLASS_ENTRY(ce, "ParseError", class_ParseError_methods);
796-
zend_ce_parse_error = zend_register_internal_class_ex(&ce, zend_ce_compile_error);
764+
register_class_ParseError(zend_ce_parse_error, zend_ce_compile_error);
797765
zend_ce_parse_error->create_object = zend_default_exception_new;
798766

799-
INIT_CLASS_ENTRY(ce, "TypeError", class_TypeError_methods);
800-
zend_ce_type_error = zend_register_internal_class_ex(&ce, zend_ce_error);
767+
register_class_TypeError(zend_ce_type_error, zend_ce_error);
801768
zend_ce_type_error->create_object = zend_default_exception_new;
802769

803-
INIT_CLASS_ENTRY(ce, "ArgumentCountError", class_ArgumentCountError_methods);
804-
zend_ce_argument_count_error = zend_register_internal_class_ex(&ce, zend_ce_type_error);
770+
register_class_ArgumentCountError(zend_ce_argument_count_error, zend_ce_type_error);
805771
zend_ce_argument_count_error->create_object = zend_default_exception_new;
806772

807-
INIT_CLASS_ENTRY(ce, "ValueError", class_ValueError_methods);
808-
zend_ce_value_error = zend_register_internal_class_ex(&ce, zend_ce_error);
773+
register_class_ValueError(zend_ce_value_error, zend_ce_error);
809774
zend_ce_value_error->create_object = zend_default_exception_new;
810775

811-
INIT_CLASS_ENTRY(ce, "ArithmeticError", class_ArithmeticError_methods);
812-
zend_ce_arithmetic_error = zend_register_internal_class_ex(&ce, zend_ce_error);
776+
register_class_ArithmeticError(zend_ce_arithmetic_error, zend_ce_error);
813777
zend_ce_arithmetic_error->create_object = zend_default_exception_new;
814778

815-
INIT_CLASS_ENTRY(ce, "DivisionByZeroError", class_DivisionByZeroError_methods);
816-
zend_ce_division_by_zero_error = zend_register_internal_class_ex(&ce, zend_ce_arithmetic_error);
779+
register_class_DivisionByZeroError(zend_ce_division_by_zero_error, zend_ce_arithmetic_error);
817780
zend_ce_division_by_zero_error->create_object = zend_default_exception_new;
818781

819-
INIT_CLASS_ENTRY(zend_ce_unwind_exit, "UnwindExit", NULL);
820-
821-
INIT_CLASS_ENTRY(ce, "UnhandledMatchError", NULL);
822-
zend_ce_unhandled_match_error = zend_register_internal_class_ex(&ce, zend_ce_error);
782+
register_class_UnhandledMatchError(zend_ce_unhandled_match_error, zend_ce_error);
823783
zend_ce_unhandled_match_error->create_object = zend_default_exception_new;
784+
785+
INIT_CLASS_ENTRY(zend_ce_unwind_exit, "UnwindExit", NULL);
824786
}
825787
/* }}} */
826788

Zend/zend_exceptions.stub.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<?php
22

3-
/** @generate-function-entries */
3+
/**
4+
* @generate-function-entries
5+
* @generate-class-entries
6+
*/
47

58
interface Throwable extends Stringable
69
{
@@ -22,6 +25,21 @@ public function getTraceAsString(): string;
2225

2326
class Exception implements Throwable
2427
{
28+
/** @var string */
29+
protected $message = "";
30+
/** @var string */
31+
private $string = "";
32+
/** @var int */
33+
protected $code = 0;
34+
/** @var string|null */
35+
protected $file = null;
36+
/** @var int|null */
37+
protected $line = null;
38+
/** @known */
39+
private array $trace = [];
40+
/** @known */
41+
private ?Throwable $previous = null;
42+
2543
final private function __clone(): void {}
2644

2745
public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null) {}
@@ -49,13 +67,38 @@ public function __toString(): string {}
4967

5068
class ErrorException extends Exception
5169
{
52-
public function __construct(string $message = "", int $code = 0, int $severity = E_ERROR, ?string $filename = null, ?int $line = null, ?Throwable $previous = null) {}
70+
/** @var int */
71+
protected $severity = E_ERROR;
72+
73+
public function __construct(
74+
string $message = "",
75+
int $code = 0,
76+
int $severity = E_ERROR,
77+
?string $filename = null,
78+
?int $line = null,
79+
?Throwable $previous = null
80+
) {}
5381

5482
final public function getSeverity(): int {}
5583
}
5684

5785
class Error implements Throwable
5886
{
87+
/** @var string */
88+
protected $message = "";
89+
/** @var string */
90+
private $string = "";
91+
/** @var int */
92+
protected $code = 0;
93+
/** @var string|null */
94+
protected $file = null;
95+
/** @var int|null */
96+
protected $line = null;
97+
/** @known */
98+
private array $trace = [];
99+
/** @known */
100+
private ?Throwable $previous = null;
101+
59102
/** @implementation-alias Exception::__clone */
60103
final private function __clone(): void {}
61104

@@ -123,3 +166,7 @@ class ArithmeticError extends Error
123166
class DivisionByZeroError extends ArithmeticError
124167
{
125168
}
169+
170+
class UnhandledMatchError extends Error
171+
{
172+
}

Zend/zend_exceptions_arginfo.h

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 3699b51b31e509c11435845c7e0d35a2608dd268 */
2+
* Stub hash: fc90f59a8c670e7874f4a7564333c5b22c0eea5e */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Throwable_getMessage, 0, 0, IS_STRING, 0)
55
ZEND_END_ARG_INFO()
@@ -180,3 +180,144 @@ static const zend_function_entry class_ArithmeticError_methods[] = {
180180
static const zend_function_entry class_DivisionByZeroError_methods[] = {
181181
ZEND_FE_END
182182
};
183+
184+
185+
static const zend_function_entry class_UnhandledMatchError_methods[] = {
186+
ZEND_FE_END
187+
};
188+
189+
#define register_class_Throwable(class_entry, class_entry_Stringable) \
190+
{ \
191+
zend_class_entry ce; \
192+
\
193+
INIT_CLASS_ENTRY(ce, "Throwable", class_Throwable_methods); \
194+
class_entry = zend_register_internal_interface(&ce); \
195+
zend_class_implements(class_entry, 1, class_entry_Stringable);
196+
}
197+
198+
#define register_class_Exception(class_entry, class_entry_Throwable) \
199+
{ \
200+
zend_class_entry ce; \
201+
\
202+
INIT_CLASS_ENTRY(ce, "Exception", class_Exception_methods); \
203+
class_entry = zend_register_internal_class_ex(&ce, NULL); \
204+
zend_class_implements(class_entry, 1, class_entry_Throwable); \
205+
\
206+
zend_declare_property_string(class_entry, "message", sizeof("message") - 1, "", ZEND_ACC_PROTECTED); \
207+
\
208+
zend_declare_property_string(class_entry, "string", sizeof("string") - 1, "", ZEND_ACC_PRIVATE); \
209+
\
210+
zend_declare_property_long(class_entry, "code", sizeof("code") - 1, 0, ZEND_ACC_PROTECTED); \
211+
\
212+
zend_declare_property_null(class_entry, "file", sizeof("file") - 1, ZEND_ACC_PROTECTED); \
213+
\
214+
zend_declare_property_null(class_entry, "line", sizeof("line") - 1, ZEND_ACC_PROTECTED); \
215+
\
216+
zval property_trace_default_value; \
217+
ZVAL_EMPTY_ARRAY(&property_trace_default_value); \
218+
zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_TRACE), &property_trace_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); \
219+
\
220+
zval property_previous_default_value; \
221+
ZVAL_NULL(&property_previous_default_value); \
222+
zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_PREVIOUS), &property_previous_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CE(class_entry_Throwable, 1, 0)); \
223+
}
224+
225+
#define register_class_ErrorException(class_entry, class_entry_Exception) \
226+
{ \
227+
zend_class_entry ce; \
228+
\
229+
INIT_CLASS_ENTRY(ce, "ErrorException", class_ErrorException_methods); \
230+
class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception); \
231+
}
232+
233+
#define register_class_Error(class_entry, class_entry_Throwable) \
234+
{ \
235+
zend_class_entry ce; \
236+
\
237+
INIT_CLASS_ENTRY(ce, "Error", class_Error_methods); \
238+
class_entry = zend_register_internal_class_ex(&ce, NULL); \
239+
zend_class_implements(class_entry, 1, class_entry_Throwable); \
240+
\
241+
zend_declare_property_string(class_entry, "message", sizeof("message") - 1, "", ZEND_ACC_PROTECTED); \
242+
\
243+
zend_declare_property_string(class_entry, "string", sizeof("string") - 1, "", ZEND_ACC_PRIVATE); \
244+
\
245+
zend_declare_property_long(class_entry, "code", sizeof("code") - 1, 0, ZEND_ACC_PROTECTED); \
246+
\
247+
zend_declare_property_null(class_entry, "file", sizeof("file") - 1, ZEND_ACC_PROTECTED); \
248+
\
249+
zend_declare_property_null(class_entry, "line", sizeof("line") - 1, ZEND_ACC_PROTECTED); \
250+
\
251+
zval property_trace_default_value; \
252+
ZVAL_EMPTY_ARRAY(&property_trace_default_value); \
253+
zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_TRACE), &property_trace_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY)); \
254+
\
255+
zval property_previous_default_value; \
256+
ZVAL_NULL(&property_previous_default_value); \
257+
zend_declare_typed_property(class_entry, ZSTR_KNOWN(ZEND_STR_PREVIOUS), &property_previous_default_value, ZEND_ACC_PRIVATE, NULL, (zend_type) ZEND_TYPE_INIT_CE(class_entry_Throwable, 1, 0)); \
258+
}
259+
260+
#define register_class_CompileError(class_entry, class_entry_Error) \
261+
{ \
262+
zend_class_entry ce; \
263+
\
264+
INIT_CLASS_ENTRY(ce, "CompileError", class_CompileError_methods); \
265+
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); \
266+
}
267+
268+
#define register_class_ParseError(class_entry, class_entry_CompileError) \
269+
{ \
270+
zend_class_entry ce; \
271+
\
272+
INIT_CLASS_ENTRY(ce, "ParseError", class_ParseError_methods); \
273+
class_entry = zend_register_internal_class_ex(&ce, class_entry_CompileError); \
274+
}
275+
276+
#define register_class_TypeError(class_entry, class_entry_Error) \
277+
{ \
278+
zend_class_entry ce; \
279+
\
280+
INIT_CLASS_ENTRY(ce, "TypeError", class_TypeError_methods); \
281+
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); \
282+
}
283+
284+
#define register_class_ArgumentCountError(class_entry, class_entry_TypeError) \
285+
{ \
286+
zend_class_entry ce; \
287+
\
288+
INIT_CLASS_ENTRY(ce, "ArgumentCountError", class_ArgumentCountError_methods); \
289+
class_entry = zend_register_internal_class_ex(&ce, class_entry_TypeError); \
290+
}
291+
292+
#define register_class_ValueError(class_entry, class_entry_Error) \
293+
{ \
294+
zend_class_entry ce; \
295+
\
296+
INIT_CLASS_ENTRY(ce, "ValueError", class_ValueError_methods); \
297+
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); \
298+
}
299+
300+
#define register_class_ArithmeticError(class_entry, class_entry_Error) \
301+
{ \
302+
zend_class_entry ce; \
303+
\
304+
INIT_CLASS_ENTRY(ce, "ArithmeticError", class_ArithmeticError_methods); \
305+
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); \
306+
}
307+
308+
#define register_class_DivisionByZeroError(class_entry, class_entry_ArithmeticError) \
309+
{ \
310+
zend_class_entry ce; \
311+
\
312+
INIT_CLASS_ENTRY(ce, "DivisionByZeroError", class_DivisionByZeroError_methods); \
313+
class_entry = zend_register_internal_class_ex(&ce, class_entry_ArithmeticError); \
314+
}
315+
316+
#define register_class_UnhandledMatchError(class_entry, class_entry_Error) \
317+
{ \
318+
zend_class_entry ce; \
319+
\
320+
INIT_CLASS_ENTRY(ce, "UnhandledMatchError", class_UnhandledMatchError_methods); \
321+
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error); \
322+
}
323+

0 commit comments

Comments
 (0)