summaryrefslogtreecommitdiff
path: root/class.c
diff options
context:
space:
mode:
authorPaul "LeoNerd" Evans <leonerd@leonerd.org.uk>2023-02-04 00:27:00 +0000
committerPaul "LeoNerd" Evans <leonerd@leonerd.org.uk>2023-02-10 12:07:02 +0000
commit24c33697796a1556af3f58e15fc4fb6b0d1538dc (patch)
treef747d7bdf730b423528f6d960db2465f9c708d4e /class.c
parent99b497aa90ed7db99d29a301b47c91fba65c9cb3 (diff)
downloadperl-24c33697796a1556af3f58e15fc4fb6b0d1538dc.tar.gz
Create a specific SV type for object instances
Diffstat (limited to 'class.c')
-rw-r--r--class.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/class.c b/class.c
index 88a4205a99..6642a01d5d 100644
--- a/class.c
+++ b/class.c
@@ -30,6 +30,20 @@ Perl_croak_kw_unless_class(pTHX_ const char *kw)
croak("Cannot '%s' outside of a 'class'", kw);
}
+#define newSVobject(fieldcount) Perl_newSVobject(aTHX_ fieldcount)
+SV *
+Perl_newSVobject(pTHX_ Size_t fieldcount)
+{
+ SV *sv = newSV_type(SVt_PVOBJ);
+
+ Newx(ObjectFIELDS(sv), fieldcount, SV *);
+ ObjectMAXFIELD(sv) = fieldcount - 1;
+
+ Zero(ObjectFIELDS(sv), fieldcount, SV *);
+
+ return sv;
+}
+
XS(injected_constructor);
XS(injected_constructor)
{
@@ -65,10 +79,12 @@ XS(injected_constructor)
}
}
- AV *fields = newAV();
- SV *self = sv_2mortal(newRV_noinc((SV *)fields));
+ SV *instance = newSVobject(aux->xhv_class_next_fieldix);
+ SV *self = sv_2mortal(newRV_noinc(instance));
sv_bless(self, stash);
+ SV **fields = ObjectFIELDS(instance);
+
/* create fields */
for(PADOFFSET fieldix = 0; fieldix < aux->xhv_class_next_fieldix; fieldix++) {
PADNAME *pn = PadnamelistARRAY(aux->xhv_class_fields)[fieldix];
@@ -93,7 +109,7 @@ XS(injected_constructor)
NOT_REACHED;
}
- av_push(fields, val);
+ fields[fieldix] = val;
}
if(aux->xhv_class_adjust_blocks) {
@@ -164,7 +180,7 @@ PP(pp_methstart)
if(!SvROK(self) ||
!SvOBJECT((rv = SvRV(self))) ||
- SvTYPE(rv) != SVt_PVAV) { /* TODO: SVt_INSTANCE */
+ SvTYPE(rv) != SVt_PVOBJ) {
HEK *namehek = CvGvNAME_HEK(curcv);
croak(
namehek ? "Cannot invoke method %" HEKf_QUOTEDPREFIX " on a non-instance" :
@@ -182,14 +198,14 @@ PP(pp_methstart)
UNOP_AUX_item *aux = cUNOP_AUX->op_aux;
if(aux) {
- assert(SvTYPE(SvRV(self)) == SVt_PVAV);
- AV *fields = MUTABLE_AV(SvRV(self));
- SV **fieldp = AvARRAY(fields);
+ assert(SvTYPE(SvRV(self)) == SVt_PVOBJ);
+ SV *instance = SvRV(self);
+ SV **fieldp = ObjectFIELDS(instance);
U32 fieldcount = (aux++)->uv;
U32 max_fieldix = (aux++)->uv;
- assert(av_count(fields) > max_fieldix);
+ assert(ObjectMAXFIELD(instance)+1 > max_fieldix);
PERL_UNUSED_VAR(max_fieldix);
for(Size_t i = 0; i < fieldcount; i++) {