[svn:parrot] r44716 - in branches/pcc_hackathon_6Mar10: include/parrot src/call

allison at svn.parrot.org allison at svn.parrot.org
Sat Mar 6 23:07:25 UTC 2010


Author: allison
Date: Sat Mar  6 23:07:24 2010
New Revision: 44716
URL: https://trac.parrot.org/parrot/changeset/44716

Log:
[pcc] Adding functions for handling calls from C, with the new order the
results have to be fetched after invocation.

Modified:
   branches/pcc_hackathon_6Mar10/include/parrot/call.h
   branches/pcc_hackathon_6Mar10/src/call/args.c
   branches/pcc_hackathon_6Mar10/src/call/pcc.c

Modified: branches/pcc_hackathon_6Mar10/include/parrot/call.h
==============================================================================
--- branches/pcc_hackathon_6Mar10/include/parrot/call.h	Sat Mar  6 22:48:18 2010	(r44715)
+++ branches/pcc_hackathon_6Mar10/include/parrot/call.h	Sat Mar  6 23:07:24 2010	(r44716)
@@ -159,6 +159,18 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
+PMC* Parrot_pcc_build_call_from_varargs(PARROT_INTERP,
+    ARGIN_NULLOK(PMC *obj),
+    ARGIN(const char *sig),
+    ARGMOD(va_list *args))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(3)
+        __attribute__nonnull__(4)
+        FUNC_MODIFIES(*args);
+
+PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
 PMC* Parrot_pcc_build_sig_object_from_op(PARROT_INTERP,
     ARGIN_NULLOK(PMC *signature),
     ARGIN(PMC * const raw_sig),
@@ -198,6 +210,18 @@
         FUNC_MODIFIES(*call_object);
 
 PARROT_EXPORT
+void Parrot_pcc_fill_params_from_varargs(PARROT_INTERP,
+    ARGMOD(PMC *call_object),
+    ARGIN(const char *signature),
+    ARGMOD(va_list *args))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        __attribute__nonnull__(4)
+        FUNC_MODIFIES(*call_object)
+        FUNC_MODIFIES(*args);
+
+PARROT_EXPORT
 void Parrot_pcc_fill_returns_from_c_args(PARROT_INTERP,
     ARGMOD_NULLOK(PMC *call_object),
     ARGIN(const char *signature),
@@ -225,6 +249,23 @@
         FUNC_MODIFIES(*arg_flags)
         FUNC_MODIFIES(*return_flags);
 
+PARROT_CAN_RETURN_NULL
+void Parrot_pcc_split_signature_string(PARROT_INTERP,
+    ARGIN(const char *signature),
+    ARGMOD(char **arg_sig),
+    ARGMOD(char **return_sig))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        __attribute__nonnull__(4)
+        FUNC_MODIFIES(*arg_sig)
+        FUNC_MODIFIES(*return_sig);
+
+#define ASSERT_ARGS_Parrot_pcc_build_call_from_varargs \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(sig) \
+    , PARROT_ASSERT_ARG(args))
 #define ASSERT_ARGS_Parrot_pcc_build_sig_object_from_op \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
@@ -244,15 +285,16 @@
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(raw_sig) \
     , PARROT_ASSERT_ARG(raw_params))
-#define ASSERT_ARGS_Parrot_pcc_fill_returns_from_c_args \
+#define ASSERT_ARGS_Parrot_pcc_fill_params_from_varargs \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(signature))
-#define ASSERT_ARGS_Parrot_pcc_fill_returns_from_op \
+    , PARROT_ASSERT_ARG(call_object) \
+    , PARROT_ASSERT_ARG(signature) \
+    , PARROT_ASSERT_ARG(args))
+#define ASSERT_ARGS_Parrot_pcc_fill_returns_from_c_args \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(raw_sig) \
-    , PARROT_ASSERT_ARG(raw_returns))
+    , PARROT_ASSERT_ARG(signature))
 #define ASSERT_ARGS_Parrot_pcc_merge_signature_for_tailcall \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
@@ -262,6 +304,12 @@
     , PARROT_ASSERT_ARG(signature) \
     , PARROT_ASSERT_ARG(arg_flags) \
     , PARROT_ASSERT_ARG(return_flags))
+#define ASSERT_ARGS_Parrot_pcc_split_signature_string \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(signature) \
+    , PARROT_ASSERT_ARG(arg_sig) \
+    , PARROT_ASSERT_ARG(return_sig))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/call/args.c */
 

Modified: branches/pcc_hackathon_6Mar10/src/call/args.c
==============================================================================
--- branches/pcc_hackathon_6Mar10/src/call/args.c	Sat Mar  6 22:48:18 2010	(r44715)
+++ branches/pcc_hackathon_6Mar10/src/call/args.c	Sat Mar  6 23:07:24 2010	(r44716)
@@ -276,14 +276,11 @@
 PARROT_CAN_RETURN_NULL
 static void parse_signature_string(PARROT_INTERP,
     ARGIN(const char *signature),
-    ARGMOD(PMC **arg_flags),
-    ARGMOD(PMC **return_flags))
+    ARGMOD(PMC **arg_flags))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
-        __attribute__nonnull__(4)
-        FUNC_MODIFIES(*arg_flags)
-        FUNC_MODIFIES(*return_flags);
+        FUNC_MODIFIES(*arg_flags);
 
 PARROT_CANNOT_RETURN_NULL
 static PMC* pmc_arg_from_c_args(PARROT_INTERP,
@@ -465,8 +462,7 @@
 #define ASSERT_ARGS_parse_signature_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(signature) \
-    , PARROT_ASSERT_ARG(arg_flags) \
-    , PARROT_ASSERT_ARG(return_flags))
+    , PARROT_ASSERT_ARG(arg_flags))
 #define ASSERT_ARGS_pmc_arg_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(args))
@@ -732,6 +728,98 @@
     }
 }
 
+/*
+
+=item C<PMC* Parrot_pcc_build_call_from_varargs(PARROT_INTERP, PMC *obj, const
+char *sig, va_list *args)>
+
+Converts a varargs list into a CallContext PMC. The CallContext stores the
+original short signature string and an array of integer types to pass on to the
+multiple dispatch search.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+PMC*
+Parrot_pcc_build_call_from_varargs(PARROT_INTERP, ARGIN_NULLOK(PMC *obj),
+        ARGIN(const char *sig), ARGMOD(va_list *args))
+{
+    ASSERT_ARGS(Parrot_pcc_build_call_from_varargs)
+    PMC         * type_tuple        = PMCNULL;
+    PMC         * arg_flags         = PMCNULL;
+    PMC         * ignored_flags     = PMCNULL;
+    PMC         * const call_object = Parrot_pmc_new(interp, enum_class_CallContext);
+    const INTVAL sig_len            = strlen(sig);
+    INTVAL       in_return_sig      = 0;
+    INTVAL       i;
+    int          append_pi          = 1;
+
+    if (!sig_len)
+        return call_object;
+
+    parse_signature_string(interp, sig, &arg_flags);
+    VTABLE_set_attr_str(interp, call_object, CONST_STRING(interp, "arg_flags"), arg_flags);
+
+    /* Process the varargs list */
+    for (i = 0; i < sig_len; ++i) {
+        const INTVAL type = sig[i];
+
+        /* Don't process returns */
+        if (in_return_sig)
+            break;
+
+        /* Regular arguments just set the value */
+        switch (type) {
+          case 'I':
+            VTABLE_push_integer(interp, call_object, va_arg(*args, INTVAL));
+            break;
+          case 'N':
+            VTABLE_push_float(interp, call_object, va_arg(*args, FLOATVAL));
+            break;
+          case 'S':
+            VTABLE_push_string(interp, call_object, va_arg(*args, STRING *));
+            break;
+          case 'P':
+            {
+                const INTVAL type_lookahead = sig[i+1];
+                PMC * const pmc_arg = va_arg(*args, PMC *);
+                if (type_lookahead == 'f') {
+                     dissect_aggregate_arg(interp, call_object, pmc_arg);
+                    i++; /* skip 'f' */
+                }
+                else {
+                    VTABLE_push_pmc(interp, call_object, clone_key_arg(interp, pmc_arg));
+                    if (type_lookahead == 'i') {
+                        if (i != 0)
+                            Parrot_ex_throw_from_c_args(interp, NULL,
+                                EXCEPTION_INVALID_OPERATION,
+                                "Dispatch: only the first argument can be an invocant");
+                        i++; /* skip 'i' */
+                        append_pi = 0; /* Don't append Pi in front of signature */
+                    }
+                }
+                break;
+            }
+          case '-':
+            in_return_sig = 1;
+            break;
+          default:
+            Parrot_ex_throw_from_c_args(interp, NULL,
+                    EXCEPTION_INVALID_OPERATION,
+                    "Dispatch: invalid argument type %c!", type);
+        }
+    }
+
+    /* Check if we have an invocant, and add it to the front of the arguments iff needed */
+    if (!PMC_IS_NULL(obj) && append_pi)
+        VTABLE_unshift_pmc(interp, call_object, obj);
+
+    return call_object;
+}
 
 /*
 
@@ -756,7 +844,6 @@
     ASSERT_ARGS(Parrot_pcc_build_sig_object_from_varargs)
     PMC         * type_tuple        = PMCNULL;
     PMC         * arg_flags         = PMCNULL;
-    PMC         * ignored_flags     = PMCNULL;
     PMC         * const call_object = Parrot_pmc_new(interp, enum_class_CallContext);
     const INTVAL sig_len            = strlen(sig);
     INTVAL       in_return_sig      = 0;
@@ -766,7 +853,7 @@
     if (!sig_len)
         return call_object;
 
-    parse_signature_string(interp, sig, &arg_flags, &ignored_flags);
+    parse_signature_string(interp, sig, &arg_flags);
     VTABLE_set_attr_str(interp, call_object, CONST_STRING(interp, "arg_flags"), arg_flags);
 
     /* Process the varargs list */
@@ -1386,8 +1473,38 @@
 {
     ASSERT_ARGS(Parrot_pcc_fill_params_from_c_args)
     va_list args;
+
+    va_start(args, signature);
+    Parrot_pcc_fill_params_from_varargs(interp, call_object, signature, &args);
+    va_end(args);
+}
+
+/*
+
+=item C<void Parrot_pcc_fill_params_from_varargs(PARROT_INTERP, PMC
+*call_object, const char *signature, va_list *args)>
+
+Gets args for the current function call and puts them into position.
+First it gets the positional non-slurpy parameters, then the positional
+slurpy parameters, then the named parameters, and finally the named
+slurpy parameters.
+
+The signature is a string in the format used for
+C<Parrot_pcc_invoke_from_sig_object>, but with no return arguments. The
+parameters are passed in as a list of references to the destination
+variables.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_pcc_fill_params_from_varargs(PARROT_INTERP, ARGMOD(PMC *call_object),
+        ARGIN(const char *signature), ARGMOD(va_list *args))
+{
+    ASSERT_ARGS(Parrot_pcc_fill_params_from_varargs)
     PMC    *raw_sig  = PMCNULL;
-    PMC    *invalid_sig = PMCNULL;
     static pcc_set_funcs function_pointers = {
         (intval_ptr_func_t)intval_param_from_c_args,
         (numval_ptr_func_t)numval_param_from_c_args,
@@ -1400,14 +1517,12 @@
         (pmc_func_t)pmc_constant_from_varargs,
     };
 
-    parse_signature_string(interp, signature, &raw_sig, &invalid_sig);
-    if (!PMC_IS_NULL(invalid_sig))
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-                "returns should not be included in the parameter list");
+    if (strlen(signature) == 0)
+        return;
 
-    va_start(args, signature);
-    fill_params(interp, call_object, raw_sig, &args, &function_pointers);
-    va_end(args);
+    parse_signature_string(interp, signature, &raw_sig);
+
+    fill_params(interp, call_object, raw_sig, args, &function_pointers);
 }
 
 /*
@@ -1961,7 +2076,6 @@
     va_list args;
     INTVAL raw_return_count = 0;
     PMC    *raw_sig         = PMCNULL;
-    PMC    *invalid_sig     = PMCNULL;
 
     static pcc_get_funcs function_pointers = {
         (intval_func_t)intval_arg_from_c_args,
@@ -1975,11 +2089,7 @@
         (pmc_func_t)pmc_constant_from_varargs,
     };
 
-    parse_signature_string(interp, signature, &raw_sig, &invalid_sig);
-
-    if (!PMC_IS_NULL(invalid_sig))
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-                "parameters should not be included in the return signature");
+    parse_signature_string(interp, signature, &raw_sig);
 
     raw_return_count = VTABLE_elements(interp, raw_sig);
 
@@ -2002,11 +2112,53 @@
     va_end(args);
 }
 
+/*
+
+=item C<void Parrot_pcc_split_signature_string(PARROT_INTERP, const char
+*signature, char **arg_sig, char **return_sig)>
+
+Splits a full signature string and creates call and return signature strings.
+The two result strings should be passed in as references to a C string.
+
+=cut
+
+*/
+
+PARROT_CAN_RETURN_NULL
+void
+Parrot_pcc_split_signature_string(PARROT_INTERP, ARGIN(const char *signature),
+        ARGMOD(char **arg_sig), ARGMOD(char **return_sig))
+{
+    ASSERT_ARGS(Parrot_pcc_split_signature_string)
+    const char *cur;
+    int arg_len = 0;
+    int ret_len = 0;
+    char *arg_tmp;
+    char *ret_tmp;
+
+    for (cur = signature; *cur != '\0'; cur++) {
+        if (*cur == '-')
+            break;
+        else
+            arg_len++;
+    }
+    ret_len = strlen(signature) - arg_len - 2;
+
+    arg_tmp = (char *) malloc(arg_len + 1);
+    ret_tmp = (char *) malloc(ret_len + 1);
+    strncpy(arg_tmp, signature, arg_len);
+    strncpy(ret_tmp, cur + 2, ret_len);
+    arg_tmp[arg_len] = '\0';
+    ret_tmp[ret_len] = '\0';
+
+    *arg_sig = arg_tmp;
+    *return_sig = ret_tmp;
+}
 
 /*
 
 =item C<static void parse_signature_string(PARROT_INTERP, const char *signature,
-PMC **arg_flags, PMC **return_flags)>
+PMC **arg_flags)>
 
 Parses a signature string and creates call and return signature integer
 arrays. The two integer arrays should be passed in as references to a
@@ -2019,7 +2171,7 @@
 PARROT_CAN_RETURN_NULL
 static void
 parse_signature_string(PARROT_INTERP, ARGIN(const char *signature),
-        ARGMOD(PMC **arg_flags), ARGMOD(PMC **return_flags))
+        ARGMOD(PMC **arg_flags))
 {
     ASSERT_ARGS(parse_signature_string)
     PMC *current_array;
@@ -2035,20 +2187,7 @@
 
         /* detect -> separator */
         if (*x == '-') {
-            /* skip '>' */
-            x++;
-
-            /* Starting a new argument, so store the previous argument,
-             * if there was one. */
-            if (set) {
-                VTABLE_push_integer(interp, current_array, flags);
-                set = 0;
-            }
-
-            /* Switch to the return argument flags. */
-            if (PMC_IS_NULL(*return_flags))
-                *return_flags = Parrot_pmc_new(interp, enum_class_ResizableIntegerArray);
-            current_array = *return_flags;
+            break;
         }
         /* parse arg type */
         else if (isupper((unsigned char)*x)) {
@@ -2115,10 +2254,15 @@
 {
     ASSERT_ARGS(Parrot_pcc_parse_signature_string)
     char * const s = Parrot_str_to_cstring(interp, signature);
+    char *arg_sig, *ret_sig;
+    Parrot_pcc_split_signature_string(interp, s, &arg_sig, &ret_sig);
     *arg_flags    = PMCNULL;
     *return_flags = PMCNULL;
-    parse_signature_string(interp, s, arg_flags, return_flags);
+    parse_signature_string(interp, arg_sig, arg_flags);
+    parse_signature_string(interp, ret_sig, return_flags);
     Parrot_str_free_cstring(s);
+    Parrot_str_free_cstring(arg_sig);
+    Parrot_str_free_cstring(ret_sig);
 }
 
 /*

Modified: branches/pcc_hackathon_6Mar10/src/call/pcc.c
==============================================================================
--- branches/pcc_hackathon_6Mar10/src/call/pcc.c	Sat Mar  6 22:48:18 2010	(r44715)
+++ branches/pcc_hackathon_6Mar10/src/call/pcc.c	Sat Mar  6 23:07:24 2010	(r44716)
@@ -64,15 +64,18 @@
         ARGIN(const char *sig), ...)
 {
     ASSERT_ARGS(Parrot_pcc_invoke_sub_from_c_args)
-    PMC    *sig_obj;
+    PMC    *call_obj;
     va_list args;
+    char *arg_sig, *ret_sig;
+    Parrot_pcc_split_signature_string(interp, sig, &arg_sig, &ret_sig);
 
     va_start(args, sig);
-    sig_obj = Parrot_pcc_build_sig_object_from_varargs(interp, PMCNULL,
-         sig, args);
+    call_obj = Parrot_pcc_build_call_from_varargs(interp, PMCNULL,
+         arg_sig, &args);
+    Parrot_pcc_invoke_from_sig_object(interp, sub_obj, call_obj);
+    Parrot_pcc_fill_params_from_varargs(interp, call_obj, ret_sig, &args);
     va_end(args);
 
-    Parrot_pcc_invoke_from_sig_object(interp, sub_obj, sig_obj);
 }
 
 


More information about the parrot-commits mailing list