4 static MGVTBL mop_constructor_vtbl;
7 mop_build_args(pTHX_ CV* const cv, I32 const ax, I32 const items){
12 if(!(SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV)){
13 croak("Single arguments to %s() must be a HASH ref", GvNAME(CvGV(cv)));
21 croak("Odd number of arguments for %s()", GvNAME(CvGV(cv)));
25 sv_2mortal((SV*)args);
27 for(i = 0; i < items; i += 2){
28 SV* const key = ST(i);
29 SV* const value = ST(i+1);
30 (void)hv_store_ent(args, key, value, 0U);
31 SvREFCNT_inc_simple_void_NN(value);
38 XS(mop_xs_constructor);
39 XS(mop_xs_constructor)
43 AV* const attrs = (AV*)MOP_mg_obj(mg);
51 assert(SvTYPE(attrs) == SVt_PVAV);
54 croak("Not enough arguments for %s()", GvNAME(CvGV(cv)));
60 croak("The constructor must be called as a class method");
63 args = mop_build_args(aTHX_ cv, ax+1, items-1);
65 stash = gv_stashsv(klass, TRUE);
66 if( stash != GvSTASH(CvGV(cv)) ){
67 SV* const metaclass = mop_class_of(aTHX_ klass);
73 mPUSHs(newRV_inc((SV*)args));
76 call_method("new_object", GIMME_V);
80 instance = sv_2mortal( MOP_mg_create_instance(mg, stash) );
81 if(!IsObject(instance)){
82 croak("create_instance() did not return an object instance");
85 len = AvFILLp(attrs) + 1;
86 for(i = 0; i < len; i++){
87 mop_attr_initialize_instance_slot(aTHX_ AvARRAY(attrs)[i], MOP_mg_vtbl(mg), instance, args);
96 mop_generate_constructor_method_xs(pTHX_ SV* const constructor, mop_instance_vtbl* const vtbl){
97 SV* const metaclass = mop_call0(aTHX_ constructor, mop_associated_metaclass);
99 CV* const xsub = newXS(NULL, mop_xs_constructor, __FILE__);
103 sv_2mortal((SV*)xsub);
105 attrs = mop_class_get_all_attributes(aTHX_ metaclass);
106 mg = sv_magicext((SV*)xsub, (SV*)attrs, PERL_MAGIC_ext, &mop_constructor_vtbl, (char*)vtbl, 0);
108 CvXSUBANY(xsub).any_ptr = (void*)mg;
114 MODULE = Class::MOP::Method::Constructor PACKAGE = Class::MOP::Method::Constructor
118 VERSIONCHECK: DISABLE
121 INSTALL_SIMPLE_READER(Method::Constructor, options);
122 INSTALL_SIMPLE_READER(Method::Constructor, associated_metaclass);
125 _generate_constructor_method_xs(SV* self, void* instance_vtbl)
127 RETVAL = mop_generate_constructor_method_xs(aTHX_ self, instance_vtbl);