version 1.0104
[p5sagit/Function-Parameters.git] / Parameters.xs
index fa8e4ee..3ca4d40 100644 (file)
@@ -220,6 +220,15 @@ static int my_sv_eq_pvn(pTHX_ SV *sv, const char *p, STRLEN n) {
 #include "padop_on_crack.c.inc"
 
 
+static void my_require(pTHX_ const char *file) {
+       SV *err;
+       require_pv(file);
+       err = ERRSV;
+       if (SvTRUE(err)) {
+               croak_sv(err);
+       }
+}
+
 enum {
        MY_ATTR_LVALUE = 0x01,
        MY_ATTR_METHOD = 0x02,
@@ -502,6 +511,8 @@ static SV *reify_type(pTHX_ Sentinel sen, const SV *declarator, SV *name) {
        int n;
        dSP;
 
+       my_require(aTHX_ "Moose/Util/TypeConstraints.pm");
+
        ENTER;
        SAVETMPS;
 
@@ -712,15 +723,6 @@ static size_t count_named_params(const ParamSpec *ps) {
        return ps->named_required.used + ps->named_optional.used;
 }
 
-static void my_require(pTHX_ const char *file) {
-       SV *err;
-       require_pv(file);
-       err = ERRSV;
-       if (SvTRUE(err)) {
-               croak_sv(err);
-       }
-}
-
 static SV *my_eval(pTHX_ Sentinel sen, I32 floor, OP *op) {
        SV *sv;
        CV *cv;
@@ -798,7 +800,9 @@ static PADOFFSET parse_param(
                                sentinel_disarm(expr_sentinel);
                        }
                        *ptype = my_eval(aTHX_ sen, floor, expr);
-                       *ptype = reify_type(aTHX_ sen, declarator, *ptype);
+                       if (!SvROK(*ptype)) {
+                               *ptype = reify_type(aTHX_ sen, declarator, *ptype);
+                       }
                        if (!sv_isobject(*ptype)) {
                                croak("In %"SVf": (%"SVf") doesn't look like a type object", SVfARG(declarator), SVfARG(*ptype));
                        }
@@ -806,7 +810,6 @@ static PADOFFSET parse_param(
                        c = lex_peek_unichar(0);
                } else if (MY_UNI_IDFIRST(c)) {
                        *ptype = parse_type(aTHX_ sen, declarator);
-                       my_require(aTHX_ "Moose/Util/TypeConstraints.pm");
                        *ptype = reify_type(aTHX_ sen, declarator, *ptype);
 
                        c = lex_peek_unichar(0);
@@ -976,10 +979,11 @@ static void register_info(pTHX_ UV key, SV *declarator, const KWSpec *kws, const
                mPUSHu(key);
        }
        /* 1 */ {
-               size_t n;
+               STRLEN n;
                char *p = SvPV(declarator, n);
                char *q = memchr(p, ' ', n);
-               mPUSHp(p, q ? (size_t)(q - p) : n);
+               SV *tmp = newSVpvn_utf8(p, q ? (size_t)(q - p) : n, SvUTF8(declarator));
+               mPUSHs(tmp);
        }
        if (!ps) {
                if (SvTRUE(kws->shift)) {
@@ -1116,6 +1120,9 @@ static int parse_fun(pTHX_ Sentinel sen, OP **pop, const char *keyword_ptr, STRL
        I32 c;
 
        declarator = sentinel_mortalize(sen, newSVpvn(keyword_ptr, keyword_len));
+       if (lex_bufutf8()) {
+               SvUTF8_on(declarator);
+       }
 
        lex_read_space(0);
 
@@ -1947,6 +1954,7 @@ static int kw_flags_enter(pTHX_ Sentinel sen, const char *kw_ptr, STRLEN kw_len,
        SV *sv, **psv;
        const char *p, *kw_active;
        STRLEN kw_active_len;
+       bool kw_is_utf8;
 
        if (!(hints = GvHV(PL_hintgv))) {
                return FALSE;
@@ -1959,6 +1967,9 @@ static int kw_flags_enter(pTHX_ Sentinel sen, const char *kw_ptr, STRLEN kw_len,
        if (kw_active_len <= kw_len) {
                return FALSE;
        }
+
+       kw_is_utf8 = lex_bufutf8();
+
        for (
                p = kw_active;
                (p = strchr(p, *kw_ptr)) &&
@@ -1982,11 +1993,16 @@ static int kw_flags_enter(pTHX_ Sentinel sen, const char *kw_ptr, STRLEN kw_len,
 #define FETCH_HINTK_INTO(NAME, PTR, LEN, X) STMT_START { \
        const char *fk_ptr_; \
        STRLEN fk_len_; \
+       I32 fk_xlen_; \
        SV *fk_sv_; \
        fk_sv_ = sentinel_mortalize(sen, newSVpvs(HINTK_ ## NAME)); \
        sv_catpvn(fk_sv_, PTR, LEN); \
        fk_ptr_ = SvPV(fk_sv_, fk_len_); \
-       if (!((X) = hv_fetch(hints, fk_ptr_, fk_len_, 0))) { \
+       fk_xlen_ = fk_len_; \
+       if (kw_is_utf8) { \
+               fk_xlen_ = -fk_xlen_; \
+       } \
+       if (!((X) = hv_fetch(hints, fk_ptr_, fk_xlen_, 0))) { \
                croak("%s: internal error: $^H{'%.*s'} not set", MY_PKG, (int)fk_len_, fk_ptr_); \
        } \
 } STMT_END