Skip to content

Commit 149da82

Browse files
committed
A few other changes
1 parent e5ace7e commit 149da82

16 files changed

+226
-68
lines changed

Zend/zend_exceptions.c

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -734,46 +734,75 @@ ZEND_METHOD(Exception, __toString)
734734
}
735735
/* }}} */
736736

737+
static void declare_exception_properties(zend_class_entry *ce)
738+
{
739+
zval val;
740+
741+
zend_declare_property_string(ce, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED);
742+
zend_declare_property_string(ce, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE);
743+
zend_declare_property_long(ce, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED);
744+
zend_declare_property_null(ce, "file", sizeof("file")-1, ZEND_ACC_PROTECTED);
745+
zend_declare_property_null(ce, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
746+
747+
ZVAL_EMPTY_ARRAY(&val);
748+
zend_declare_typed_property(
749+
ce, ZSTR_KNOWN(ZEND_STR_TRACE), &val, ZEND_ACC_PRIVATE, NULL,
750+
(zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY));
751+
752+
ZVAL_NULL(&val);
753+
zend_declare_typed_property(
754+
ce, ZSTR_KNOWN(ZEND_STR_PREVIOUS), &val, ZEND_ACC_PRIVATE, NULL,
755+
(zend_type) ZEND_TYPE_INIT_CE(zend_ce_throwable, /* allow_null */ 1, 0));
756+
}
757+
737758
void zend_register_default_exception(void) /* {{{ */
738759
{
739-
register_class_Throwable(zend_ce_throwable, zend_ce_stringable);
760+
zend_class_entry ce;
761+
762+
zend_ce_throwable = register_class_Throwable(zend_ce_stringable);
740763
zend_ce_throwable->interface_gets_implemented = zend_implement_throwable;
741764

742765
memcpy(&default_exception_handlers, &std_object_handlers, sizeof(zend_object_handlers));
743766
default_exception_handlers.clone_obj = NULL;
744767

745-
register_class_Exception(zend_ce_exception, zend_ce_throwable);
768+
INIT_CLASS_ENTRY(ce, "Exception", class_Exception_methods);
769+
zend_ce_exception = zend_register_internal_class_ex(&ce, NULL);
746770
zend_ce_exception->create_object = zend_default_exception_new;
771+
zend_class_implements(zend_ce_exception, 1, zend_ce_throwable);
772+
declare_exception_properties(zend_ce_exception);
747773

748-
register_class_ErrorException(zend_ce_error_exception, zend_ce_exception);
774+
zend_ce_error_exception = register_class_ErrorException(zend_ce_exception);
749775
zend_ce_error_exception->create_object = zend_error_exception_new;
750776
zend_declare_property_long(zend_ce_error_exception, "severity", sizeof("severity")-1, E_ERROR, ZEND_ACC_PROTECTED);
751777

752-
register_class_Error(zend_ce_error, zend_ce_throwable);
778+
INIT_CLASS_ENTRY(ce, "Error", class_Error_methods);
779+
zend_ce_error = zend_register_internal_class_ex(&ce, NULL);
753780
zend_ce_error->create_object = zend_default_exception_new;
781+
zend_class_implements(zend_ce_error, 1, zend_ce_throwable);
782+
declare_exception_properties(zend_ce_error);
754783

755-
register_class_CompileError(zend_ce_compile_error, zend_ce_error);
784+
zend_ce_compile_error = register_class_CompileError(zend_ce_error);
756785
zend_ce_compile_error->create_object = zend_default_exception_new;
757786

758-
register_class_ParseError(zend_ce_parse_error, zend_ce_compile_error);
787+
zend_ce_parse_error = register_class_ParseError(zend_ce_compile_error);
759788
zend_ce_parse_error->create_object = zend_default_exception_new;
760789

761-
register_class_TypeError(zend_ce_type_error, zend_ce_error);
790+
zend_ce_type_error = register_class_TypeError(zend_ce_error);
762791
zend_ce_type_error->create_object = zend_default_exception_new;
763792

764-
register_class_ArgumentCountError(zend_ce_argument_count_error, zend_ce_type_error);
793+
zend_ce_argument_count_error = register_class_ArgumentCountError(zend_ce_type_error);
765794
zend_ce_argument_count_error->create_object = zend_default_exception_new;
766795

767-
register_class_ValueError(zend_ce_value_error, zend_ce_error);
796+
zend_ce_value_error = register_class_ValueError(zend_ce_error);
768797
zend_ce_value_error->create_object = zend_default_exception_new;
769798

770-
register_class_ArithmeticError(zend_ce_arithmetic_error, zend_ce_error);
799+
zend_ce_arithmetic_error = register_class_ArithmeticError(zend_ce_error);
771800
zend_ce_arithmetic_error->create_object = zend_default_exception_new;
772801

773-
register_class_DivisionByZeroError(zend_ce_division_by_zero_error, zend_ce_arithmetic_error);
802+
zend_ce_division_by_zero_error = register_class_DivisionByZeroError(zend_ce_arithmetic_error);
774803
zend_ce_division_by_zero_error->create_object = zend_default_exception_new;
775804

776-
register_class_UnhandledMatchError(zend_ce_unhandled_match_error, zend_ce_error);
805+
zend_ce_unhandled_match_error = register_class_UnhandledMatchError(zend_ce_error);
777806
zend_ce_unhandled_match_error->create_object = zend_default_exception_new;
778807

779808
INIT_CLASS_ENTRY(zend_ce_unwind_exit, "UnwindExit", NULL);

Zend/zend_exceptions_arginfo.h

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -185,18 +185,20 @@ static const zend_function_entry class_UnhandledMatchError_methods[] = {
185185
ZEND_FE_END
186186
};
187187

188-
void register_class_Throwable(zend_class_entry *class_entry, zend_class_entry *class_entry_Stringable)
188+
zend_class_entry *register_class_Throwable(zend_class_entry *class_entry_Stringable)
189189
{
190-
zend_class_entry ce;
190+
zend_class_entry ce, *class_entry;
191191

192192
INIT_CLASS_ENTRY(ce, "Throwable", class_Throwable_methods);
193193
class_entry = zend_register_internal_interface(&ce);
194194
zend_class_implements(class_entry, 1, class_entry_Stringable);
195+
196+
return class_entry;
195197
}
196198

197-
void register_class_Exception(zend_class_entry *class_entry, zend_class_entry *class_entry_Throwable)
199+
zend_class_entry *register_class_Exception(zend_class_entry *class_entry_Throwable)
198200
{
199-
zend_class_entry ce;
201+
zend_class_entry ce, *class_entry;
200202

201203
INIT_CLASS_ENTRY(ce, "Exception", class_Exception_methods);
202204
class_entry = zend_register_internal_class_ex(&ce, NULL);
@@ -219,19 +221,23 @@ void register_class_Exception(zend_class_entry *class_entry, zend_class_entry *c
219221
zval property_previous_default_value;
220222
ZVAL_NULL(&property_previous_default_value);
221223
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));
224+
225+
return class_entry;
222226
}
223227

224-
void register_class_ErrorException(zend_class_entry *class_entry, zend_class_entry *class_entry_Exception)
228+
zend_class_entry *register_class_ErrorException(zend_class_entry *class_entry_Exception)
225229
{
226-
zend_class_entry ce;
230+
zend_class_entry ce, *class_entry;
227231

228232
INIT_CLASS_ENTRY(ce, "ErrorException", class_ErrorException_methods);
229233
class_entry = zend_register_internal_class_ex(&ce, class_entry_Exception);
234+
235+
return class_entry;
230236
}
231237

232-
void register_class_Error(zend_class_entry *class_entry, zend_class_entry *class_entry_Throwable)
238+
zend_class_entry *register_class_Error(zend_class_entry *class_entry_Throwable)
233239
{
234-
zend_class_entry ce;
240+
zend_class_entry ce, *class_entry;
235241

236242
INIT_CLASS_ENTRY(ce, "Error", class_Error_methods);
237243
class_entry = zend_register_internal_class_ex(&ce, NULL);
@@ -254,69 +260,87 @@ void register_class_Error(zend_class_entry *class_entry, zend_class_entry *class
254260
zval property_previous_default_value;
255261
ZVAL_NULL(&property_previous_default_value);
256262
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));
263+
264+
return class_entry;
257265
}
258266

259-
void register_class_CompileError(zend_class_entry *class_entry, zend_class_entry *class_entry_Error)
267+
zend_class_entry *register_class_CompileError(zend_class_entry *class_entry_Error)
260268
{
261-
zend_class_entry ce;
269+
zend_class_entry ce, *class_entry;
262270

263271
INIT_CLASS_ENTRY(ce, "CompileError", class_CompileError_methods);
264272
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error);
273+
274+
return class_entry;
265275
}
266276

267-
void register_class_ParseError(zend_class_entry *class_entry, zend_class_entry *class_entry_CompileError)
277+
zend_class_entry *register_class_ParseError(zend_class_entry *class_entry_CompileError)
268278
{
269-
zend_class_entry ce;
279+
zend_class_entry ce, *class_entry;
270280

271281
INIT_CLASS_ENTRY(ce, "ParseError", class_ParseError_methods);
272282
class_entry = zend_register_internal_class_ex(&ce, class_entry_CompileError);
283+
284+
return class_entry;
273285
}
274286

275-
void register_class_TypeError(zend_class_entry *class_entry, zend_class_entry *class_entry_Error)
287+
zend_class_entry *register_class_TypeError(zend_class_entry *class_entry_Error)
276288
{
277-
zend_class_entry ce;
289+
zend_class_entry ce, *class_entry;
278290

279291
INIT_CLASS_ENTRY(ce, "TypeError", class_TypeError_methods);
280292
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error);
293+
294+
return class_entry;
281295
}
282296

283-
void register_class_ArgumentCountError(zend_class_entry *class_entry, zend_class_entry *class_entry_TypeError)
297+
zend_class_entry *register_class_ArgumentCountError(zend_class_entry *class_entry_TypeError)
284298
{
285-
zend_class_entry ce;
299+
zend_class_entry ce, *class_entry;
286300

287301
INIT_CLASS_ENTRY(ce, "ArgumentCountError", class_ArgumentCountError_methods);
288302
class_entry = zend_register_internal_class_ex(&ce, class_entry_TypeError);
303+
304+
return class_entry;
289305
}
290306

291-
void register_class_ValueError(zend_class_entry *class_entry, zend_class_entry *class_entry_Error)
307+
zend_class_entry *register_class_ValueError(zend_class_entry *class_entry_Error)
292308
{
293-
zend_class_entry ce;
309+
zend_class_entry ce, *class_entry;
294310

295311
INIT_CLASS_ENTRY(ce, "ValueError", class_ValueError_methods);
296312
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error);
313+
314+
return class_entry;
297315
}
298316

299-
void register_class_ArithmeticError(zend_class_entry *class_entry, zend_class_entry *class_entry_Error)
317+
zend_class_entry *register_class_ArithmeticError(zend_class_entry *class_entry_Error)
300318
{
301-
zend_class_entry ce;
319+
zend_class_entry ce, *class_entry;
302320

303321
INIT_CLASS_ENTRY(ce, "ArithmeticError", class_ArithmeticError_methods);
304322
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error);
323+
324+
return class_entry;
305325
}
306326

307-
void register_class_DivisionByZeroError(zend_class_entry *class_entry, zend_class_entry *class_entry_ArithmeticError)
327+
zend_class_entry *register_class_DivisionByZeroError(zend_class_entry *class_entry_ArithmeticError)
308328
{
309-
zend_class_entry ce;
329+
zend_class_entry ce, *class_entry;
310330

311331
INIT_CLASS_ENTRY(ce, "DivisionByZeroError", class_DivisionByZeroError_methods);
312332
class_entry = zend_register_internal_class_ex(&ce, class_entry_ArithmeticError);
333+
334+
return class_entry;
313335
}
314336

315-
void register_class_UnhandledMatchError(zend_class_entry *class_entry, zend_class_entry *class_entry_Error)
337+
zend_class_entry *register_class_UnhandledMatchError(zend_class_entry *class_entry_Error)
316338
{
317-
zend_class_entry ce;
339+
zend_class_entry ce, *class_entry;
318340

319341
INIT_CLASS_ENTRY(ce, "UnhandledMatchError", class_UnhandledMatchError_methods);
320342
class_entry = zend_register_internal_class_ex(&ce, class_entry_Error);
343+
344+
return class_entry;
321345
}
322346

build/gen_stub.php

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -725,13 +725,14 @@ function (Expr $expr) use (&$defaultValueConstant) {
725725
if ($this->type) {
726726
$typeFlags = $this->type->tryToRepresentableType();
727727
if ($typeFlags === null) {
728-
throw new Exception("Unimplemented property type");
728+
echo "Skipping code generation for property $this->name, because it has an unimplemented type\n";
729+
return "";
729730
}
730731

731732
if ($typeFlags->classType) {
732733
$simpleType = $this->type->tryToSimpleType();
733734
if ($simpleType) {
734-
$typeCode = "(zend_type) ZEND_TYPE_INIT_CE(class_entry_" . $typeFlags->classType->toEscapedName() . ", " . ((int) $this->type->isNullable()) . ", 0)";
735+
$typeCode = "(zend_type) ZEND_TYPE_INIT_CE(class_entry_" . str_replace("_", "\\", $typeFlags->classType->name) . ", " . ((int) $this->type->isNullable()) . ", 0)";
735736
} else {
736737
throw new Exception("Property $this->name has an unsupported union type");
737738
}
@@ -874,6 +875,8 @@ class ClassInfo {
874875
public $flags;
875876
/** @var bool */
876877
public $isClass;
878+
/** @var string|null */
879+
public $alias;
877880
/** @var bool */
878881
public $isDeprecated;
879882
/** @var bool */
@@ -897,6 +900,7 @@ public function __construct(
897900
Name $name,
898901
int $flags,
899902
bool $isClass,
903+
?string $alias,
900904
bool $isDeprecated,
901905
bool $isStrictProperties,
902906
array $extends,
@@ -907,6 +911,7 @@ public function __construct(
907911
$this->name = $name;
908912
$this->flags = $flags;
909913
$this->isClass = $isClass;
914+
$this->alias = $alias;
910915
$this->isDeprecated = $isDeprecated;
911916
$this->isStrictProperties = $isStrictProperties;
912917
$this->extends = $extends;
@@ -917,12 +922,12 @@ public function __construct(
917922

918923
public function getRegistration(): string
919924
{
920-
$params = ["zend_class_entry *class_entry"];
925+
$params = [];
921926
foreach ($this->extends as $extends) {
922-
$params[] = "zend_class_entry *class_entry_$extends";
927+
$params[] = "zend_class_entry *class_entry_" . implode("_", $extends->parts);
923928
}
924929
foreach ($this->implements as $implements) {
925-
$params[] = "zend_class_entry *class_entry_$implements";
930+
$params[] = "zend_class_entry *class_entry_" . implode("_", $implements->parts);
926931
}
927932
foreach ($this->propertyInfos as $property) {
928933
$type = $property->type;
@@ -932,20 +937,28 @@ public function getRegistration(): string
932937

933938
$representableType = $type->tryToRepresentableType();
934939
if ($representableType && $representableType->classType) {
935-
$params[] = "zend_class_entry *class_entry_" . $representableType->classType->toEscapedName();
940+
$params[] = "zend_class_entry *class_entry_" . str_replace("\\", "_", $representableType->classType->toEscapedName());
936941
}
937942
}
938943
$params = array_unique($params);
939944

940-
$code = "void register_class_{$this->name}(";
941-
$code .= implode(", ", $params);
942-
$code .= ")\n";
945+
$escapedName = implode("_", $this->name->parts);
946+
947+
$code = "zend_class_entry *register_class_$escapedName(" . implode(", ", $params) . ")\n";
943948

944949
$code .= "{\n";
945-
$code .= "\tzend_class_entry ce;\n\n";
946-
$code .= "\tINIT_CLASS_ENTRY(ce, \"{$this->name}\", class_{$this->name}_methods);\n";
950+
$code .= "\tzend_class_entry ce, *class_entry;\n\n";
951+
if (count($this->name->parts) > 1) {
952+
$className = array_pop($this->name->parts);
953+
$namespace = $this->name->toCodeString();
954+
955+
$code .= "\tINIT_NS_CLASS_ENTRY(ce, \"$namespace\", \"$className\", class_{$escapedName}_methods);\n";
956+
} else {
957+
$code .= "\tINIT_CLASS_ENTRY(ce, \"$this->name\", class_{$escapedName}_methods);\n";
958+
}
959+
947960
if ($this->isClass) {
948-
$code .= "\tclass_entry = zend_register_internal_class_ex(&ce, " . (isset($this->extends[0]) ? "class_entry_" . $this->extends[0] : "NULL") . ");\n";
961+
$code .= "\tclass_entry = zend_register_internal_class_ex(&ce, " . (isset($this->extends[0]) ? "class_entry_" . str_replace("\\", "_", $this->extends[0]) : "NULL") . ");\n";
949962
} else {
950963
$code .= "\tclass_entry = zend_register_internal_interface(&ce);\n";
951964
}
@@ -954,19 +967,25 @@ public function getRegistration(): string
954967
}
955968

956969
foreach ($this->implements as $implements) {
957-
$code .= "\tzend_class_implements(class_entry, 1, class_entry_$implements);\n";
970+
$code .= "\tzend_class_implements(class_entry, 1, class_entry_" . implode("_", $implements->parts) . ");\n";
958971
}
959972

960973
if ($this->isClass === false && $this->extends) {
961974
foreach ($this->extends as $extends) {
962-
$code .= "\tzend_class_implements(class_entry, 1, class_entry_$extends);\n";
975+
$code .= "\tzend_class_implements(class_entry, 1, class_entry_" . implode("_", $extends->parts) . ");\n";
963976
}
964977
}
965978

979+
if ($this->alias) {
980+
$code .= "\tzend_register_class_alias(\"" . str_replace("_", "\\", $this->alias) . "\", class_entry);\n";
981+
}
982+
966983
foreach ($this->propertyInfos as $property) {
967984
$code .= $property->getDeclaration();
968985
}
969986

987+
$code .= "\n\treturn class_entry;\n";
988+
970989
$code .= "}\n\n";
971990

972991
return $code;
@@ -1269,13 +1288,16 @@ function parseProperty(
12691288
function parseClass(Name $name, Stmt\ClassLike $class, array $properties, array $methods): ClassInfo {
12701289
$flags = $class instanceof Class_ ? $class->flags : 0;
12711290
$comment = $class->getDocComment();
1291+
$alias = null;
12721292
$isDeprecated = false;
12731293
$isStrictProperties = false;
12741294

12751295
if ($comment) {
12761296
$tags = parseDocComment($comment);
12771297
foreach ($tags as $tag) {
1278-
if ($tag->name === 'deprecated') {
1298+
if ($tag->name === 'alias') {
1299+
$alias = $tag->getValue();
1300+
} else if ($tag->name === 'deprecated') {
12791301
$isDeprecated = true;
12801302
} else if ($tag->name === 'strict-properties') {
12811303
$isStrictProperties = true;
@@ -1299,6 +1321,7 @@ function parseClass(Name $name, Stmt\ClassLike $class, array $properties, array
12991321
$name,
13001322
$flags,
13011323
$class instanceof Class_,
1324+
$alias,
13021325
$isDeprecated,
13031326
$isStrictProperties,
13041327
$extends,

0 commit comments

Comments
 (0)