@@ -1031,6 +1031,26 @@ Perl_class_add_field(pTHX_ HV *stash, PADNAME *pn)
1031
1031
PadnameREFCNT_inc (pn );
1032
1032
}
1033
1033
1034
+ /* Adds a pad entry to PL_compcv to make the given field visible. This works
1035
+ * even before the field has been properly `intro_my()`'ed and is thus usable
1036
+ * during attributes declared on the same newly-field.
1037
+ */
1038
+
1039
+ #define pad_import_field (fieldpn ) S_pad_import_field(aTHX_ fieldpn)
1040
+ static PADOFFSET
1041
+ S_pad_import_field (pTHX_ PADNAME * fieldpn )
1042
+ {
1043
+ assert (PadnameIsFIELD (fieldpn ));
1044
+
1045
+ /* We can't just pad_findmy_pvn() because the actual field may not have been
1046
+ * intro_my()'ed yet */
1047
+ PADNAME * name = newPADNAMEouter (fieldpn );
1048
+ PADOFFSET padix = pad_alloc (OP_PADSV , SVs_PADMY );
1049
+ padnamelist_store (PL_comppad_name , padix , name );
1050
+
1051
+ return padix ;
1052
+ }
1053
+
1034
1054
static void
1035
1055
apply_field_attribute_param (pTHX_ PADNAME * pn , SV * value )
1036
1056
{
@@ -1073,10 +1093,9 @@ apply_field_attribute_reader(pTHX_ PADNAME *pn, SV *value)
1073
1093
if (!valid_identifier_sv (value ))
1074
1094
croak ("%" SVf_QUOTEDPREFIX " is not a valid name for a generated method" , value );
1075
1095
1076
- PADOFFSET fieldix = PadnameFIELDINFO (pn )-> fieldix ;
1077
-
1078
1096
I32 floor_ix = start_subparse (FALSE, 0 );
1079
1097
SAVEFREESV (PL_compcv );
1098
+ CvIsMETHOD_on (PL_compcv );
1080
1099
1081
1100
I32 save_ix = block_start (TRUE);
1082
1101
@@ -1085,25 +1104,9 @@ apply_field_attribute_reader(pTHX_ PADNAME *pn, SV *value)
1085
1104
padix = pad_add_name_pvs ("$self" , 0 , NULL , NULL );
1086
1105
assert (padix == PADIX_SELF );
1087
1106
1088
- padix = pad_add_name_pvn ( PadnamePV ( pn ), PadnameLEN ( pn ), 0 , NULL , NULL );
1107
+ padix = pad_import_field ( pn );
1089
1108
intro_my ();
1090
1109
1091
- OP * methstartop ;
1092
- {
1093
- UNOP_AUX_item * aux ;
1094
- aux = (UNOP_AUX_item * )PerlMemShared_malloc (
1095
- sizeof (UNOP_AUX_item ) * (2 + 2 ));
1096
-
1097
- UNOP_AUX_item * ap = aux ;
1098
- (ap ++ )-> uv = 1 ; /* fieldcount */
1099
- (ap ++ )-> uv = fieldix ; /* max_fieldix */
1100
-
1101
- (ap ++ )-> uv = padix ;
1102
- (ap ++ )-> uv = fieldix ;
1103
-
1104
- methstartop = newUNOP_AUX (OP_METHSTART , 0 , NULL , aux );
1105
- }
1106
-
1107
1110
OP * argcheckop ;
1108
1111
{
1109
1112
struct op_argcheck_aux * aux = (struct op_argcheck_aux * )
@@ -1132,7 +1135,6 @@ apply_field_attribute_reader(pTHX_ PADNAME *pn, SV *value)
1132
1135
}
1133
1136
1134
1137
OP * ops = newLISTOPn (OP_LINESEQ , 0 ,
1135
- methstartop ,
1136
1138
argcheckop ,
1137
1139
retop ,
1138
1140
NULL );
@@ -1178,10 +1180,9 @@ apply_field_attribute_writer(pTHX_ PADNAME *pn, SV *value)
1178
1180
if (!valid_identifier_sv (value ))
1179
1181
croak ("%" SVf_QUOTEDPREFIX " is not a valid name for a generated method" , value );
1180
1182
1181
- PADOFFSET fieldix = PadnameFIELDINFO (pn )-> fieldix ;
1182
-
1183
1183
I32 floor_ix = start_subparse (FALSE, 0 );
1184
1184
SAVEFREESV (PL_compcv );
1185
+ CvIsMETHOD_on (PL_compcv );
1185
1186
1186
1187
I32 save_ix = block_start (TRUE);
1187
1188
@@ -1190,25 +1191,9 @@ apply_field_attribute_writer(pTHX_ PADNAME *pn, SV *value)
1190
1191
padix = pad_add_name_pvs ("$self" , 0 , NULL , NULL );
1191
1192
assert (padix == PADIX_SELF );
1192
1193
1193
- padix = pad_add_name_pvn ( PadnamePV ( pn ), PadnameLEN ( pn ), 0 , NULL , NULL );
1194
+ padix = pad_import_field ( pn );
1194
1195
intro_my ();
1195
1196
1196
- OP * methstartop ;
1197
- {
1198
- UNOP_AUX_item * aux ;
1199
- aux = (UNOP_AUX_item * )PerlMemShared_malloc (
1200
- sizeof (UNOP_AUX_item ) * (2 + 2 ));
1201
-
1202
- UNOP_AUX_item * ap = aux ;
1203
- (ap ++ )-> uv = 1 ; /* fieldcount */
1204
- (ap ++ )-> uv = fieldix ; /* max_fieldix */
1205
-
1206
- (ap ++ )-> uv = padix ;
1207
- (ap ++ )-> uv = fieldix ;
1208
-
1209
- methstartop = newUNOP_AUX (OP_METHSTART , 0 , NULL , aux );
1210
- }
1211
-
1212
1197
OP * argcheckop ;
1213
1198
{
1214
1199
struct op_argcheck_aux * aux = (struct op_argcheck_aux * )
@@ -1230,7 +1215,6 @@ apply_field_attribute_writer(pTHX_ PADNAME *pn, SV *value)
1230
1215
newPADxVOP (OP_PADSV , 0 , PADIX_SELF ));
1231
1216
1232
1217
OP * ops = newLISTOPn (OP_LINESEQ , 0 ,
1233
- methstartop ,
1234
1218
argcheckop ,
1235
1219
assignop ,
1236
1220
retop ,
0 commit comments