+ POPSTACK;
+ if (IN_PERL_COMPILETIME) {
+ CopHINTS_set(PL_curcop, PL_hints);
+ }
+ if (!SvROK(retval) || SvTYPE(SvRV(retval)) != SVt_PVHV) {
+ if (SvPOK(retval))
+
+ /* If caller wants to handle missing properties, let them */
+ if (return_if_undef) {
+ return NULL;
+ }
+ Perl_croak(aTHX_
+ "Can't find Unicode property definition \"%"SVf"\"",
+ SVfARG(retval));
+ Perl_croak(aTHX_ "SWASHNEW didn't return an HV ref");
+ }
+ } /* End of calling the module to find the swash */
+
+ /* Make sure there is an inversion list for binary properties */
+ if (minbits == 1) {
+ SV** swash_invlistsvp = NULL;
+ SV* swash_invlist = NULL;
+ bool invlist_in_swash_is_valid = FALSE;
+ HV* swash_hv = NULL;
+
+ /* If this operation fetched a swash, get its already existing
+ * inversion list or create one for it */
+ if (retval != &PL_sv_undef) {
+ swash_hv = MUTABLE_HV(SvRV(retval));
+
+ swash_invlistsvp = hv_fetchs(swash_hv, "INVLIST", FALSE);
+ if (swash_invlistsvp) {
+ swash_invlist = *swash_invlistsvp;
+ invlist_in_swash_is_valid = TRUE;
+ }
+ else {
+ swash_invlist = _swash_to_invlist(retval);
+ }
+ }
+
+ /* If an inversion list was passed in, have to include it */
+ if (invlist) {
+
+ /* Any fetched swash will by now have an inversion list in it;
+ * otherwise <swash_invlist> will be NULL, indicating that we
+ * didn't fetch a swash */
+ if (swash_invlist) {
+
+ /* Add the passed-in inversion list, which invalidates the one
+ * already stored in the swash */
+ invlist_in_swash_is_valid = FALSE;
+ _invlist_union(invlist, swash_invlist, &swash_invlist);
+ }
+ else {
+
+ /* Here, there is no swash already. Set up a minimal one */
+ swash_hv = newHV();
+ retval = newRV_inc(MUTABLE_SV(swash_hv));
+ swash_invlist = invlist;
+ }
+
+ if (passed_in_invlist_has_user_defined_property) {
+ if (! hv_stores(swash_hv, "USER_DEFINED", newSVuv(1))) {
+ Perl_croak(aTHX_ "panic: hv_store() unexpectedly failed");
+ }
+ }
+ }
+
+ /* Here, we have computed the union of all the passed-in data. It may
+ * be that there was an inversion list in the swash which didn't get
+ * touched; otherwise save the one computed one */
+ if (! invlist_in_swash_is_valid) {
+ if (! hv_stores(MUTABLE_HV(SvRV(retval)), "INVLIST", swash_invlist))
+ {
+ Perl_croak(aTHX_ "panic: hv_store() unexpectedly failed");
+ }
+ }