[svn:parrot] r40649 - in branches/pcc_arg_unify: include/parrot src src/call

allison at svn.parrot.org allison at svn.parrot.org
Wed Aug 19 06:10:57 UTC 2009


Author: allison
Date: Wed Aug 19 06:10:48 2009
New Revision: 40649
URL: https://trac.parrot.org/parrot/changeset/40649

Log:
[pcc] Fixup passing exception object to exception handler to work with
new argument passing scheme. Includes a hack for backward compatibility
to allow 'get_results' to fetch the argument. Will be deprecated in the
next cycle.

Modified:
   branches/pcc_arg_unify/include/parrot/call.h
   branches/pcc_arg_unify/src/call/pcc.c
   branches/pcc_arg_unify/src/exceptions.c

Modified: branches/pcc_arg_unify/include/parrot/call.h
==============================================================================
--- branches/pcc_arg_unify/include/parrot/call.h	Wed Aug 19 01:26:03 2009	(r40648)
+++ branches/pcc_arg_unify/include/parrot/call.h	Wed Aug 19 06:10:48 2009	(r40649)
@@ -16,6 +16,20 @@
 #ifndef PARROT_INTER_CALL_H_GUARD
 #define PARROT_INTER_CALL_H_GUARD
 
+typedef enum {
+    CALLSIGNATURE_is_exception_FLAG      = PObj_private0_FLAG,
+} callsignature_flags_enum;
+
+#define CALLSIGNATURE_get_FLAGS(o) (PObj_get_FLAGS(o))
+#define CALLSIGNATURE_flag_TEST(flag, o) (CALLSIGNATURE_get_FLAGS(o) & CALLSIGNATURE_ ## flag ## _FLAG)
+#define CALLSIGNATURE_flag_SET(flag, o) (CALLSIGNATURE_get_FLAGS(o) |= CALLSIGNATURE_ ## flag ## _FLAG)
+#define CALLSIGNATURE_flag_CLEAR(flag, o) (CALLSIGNATURE_get_FLAGS(o) &= ~(UINTVAL)(CALLSIGNATURE_ ## flag ## _FLAG))
+
+/* Mark if the CallSignature is for an exception handler */
+#define CALLSIGNATURE_is_exception_TEST(o)  CALLSIGNATURE_flag_TEST(is_exception, (o))
+#define CALLSIGNATURE_is_exception_SET(o)   CALLSIGNATURE_flag_SET(is_exception, (o))
+#define CALLSIGNATURE_is_exception_CLEAR(o) CALLSIGNATURE_flag_CLEAR(is_exception, (o))
+
 typedef enum call_state_mode {
     /* argument fetching/putting modes */
     CALL_STATE_SIG     = 0x100, /* runops, nci. In case we're interfacing with

Modified: branches/pcc_arg_unify/src/call/pcc.c
==============================================================================
--- branches/pcc_arg_unify/src/call/pcc.c	Wed Aug 19 01:26:03 2009	(r40648)
+++ branches/pcc_arg_unify/src/call/pcc.c	Wed Aug 19 06:10:48 2009	(r40649)
@@ -621,7 +621,7 @@
 
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
+PARROT_CAN_RETURN_NULL
 PMC*
 Parrot_pcc_build_sig_object_returns_from_op(PARROT_INTERP, ARGIN_NULLOK(PMC *signature),
         ARGIN(PMC *raw_sig), ARGIN(opcode_t *raw_args))
@@ -640,6 +640,16 @@
     else
         call_object = signature;
 
+    /* A hack to support 'get_results' as the way of fetching the
+     * exception object inside an exception handler. */
+    if (CALLSIGNATURE_is_exception_TEST(call_object)) {
+        const INTVAL raw_index = raw_args[2];
+        PMC *exception_object = 
+                VTABLE_get_pmc_keyed_int(interp, call_object, 0);
+        CTX_REG_PMC(ctx, raw_index) = exception_object;
+        return NULL;
+    }
+
     VTABLE_set_attr_str(interp, call_object, CONST_STRING(interp, "return_flags"), raw_sig);
     VTABLE_set_attr_str(interp, call_object, CONST_STRING(interp, "returns"), returns);
 

Modified: branches/pcc_arg_unify/src/exceptions.c
==============================================================================
--- branches/pcc_arg_unify/src/exceptions.c	Wed Aug 19 01:26:03 2009	(r40648)
+++ branches/pcc_arg_unify/src/exceptions.c	Wed Aug 19 06:10:48 2009	(r40649)
@@ -38,24 +38,18 @@
         __attribute__nonnull__(3);
 
 PARROT_CAN_RETURN_NULL
-static opcode_t * pass_exception_args(PARROT_INTERP,
+static void pass_exception_args(PARROT_INTERP,
     ARGIN(const char *sig),
-    ARGIN(opcode_t *dest),
-    ARGIN(Parrot_Context * old_ctx),
     ...)
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3)
-        __attribute__nonnull__(4);
+        __attribute__nonnull__(2);
 
 #define ASSERT_ARGS_build_exception_from_args __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(format)
 #define ASSERT_ARGS_pass_exception_args __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
-    || PARROT_ASSERT_ARG(sig) \
-    || PARROT_ASSERT_ARG(dest) \
-    || PARROT_ASSERT_ARG(old_ctx)
+    || PARROT_ASSERT_ARG(sig)
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
@@ -240,20 +234,7 @@
     }
 
     address    = VTABLE_invoke(interp, handler, dest);
-
-    /* XXX This is an obvious hack. We need to identify here whether this is
-       an ExceptionHandler proper or a PIR-defined subclass. This conditional
-       monstrosity attempts to check whether this is an object of a PIR-defined
-       subclass. When we have garbage-collectable PMCs, we shouldn't need to do
-       this nonsense. See TT#154 for details */
-    if (handler->vtable->base_type == enum_class_Object) {
-        /* Don't know what to do here to make sure the exception parameter gets
-           passed properly. */
-    }
-    /* Set up the continuation context of the handler in the interpreter. */
-    else if (PMC_cont(handler)->current_results)
-        address = pass_exception_args(interp, "P", address,
-                CONTEXT(interp), exception);
+    pass_exception_args(interp, "P", exception);
 
     if (PObj_get_FLAGS(handler) & SUB_FLAG_C_HANDLER) {
         /* it's a C exception handler */
@@ -267,8 +248,7 @@
 
 /*
 
-=item C<static opcode_t * pass_exception_args(PARROT_INTERP, const char *sig,
-opcode_t *dest, Parrot_Context * old_ctx, ...)>
+=item C<static opcode_t * pass_exception_args(PARROT_INTERP, const char *sig, ...)>
 
 Passes arguments to the exception handler routine. These are retrieved with
 the .get_results() directive in PIR code.
@@ -278,19 +258,20 @@
 */
 
 PARROT_CAN_RETURN_NULL
-static opcode_t *
-pass_exception_args(PARROT_INTERP, ARGIN(const char *sig),
-        ARGIN(opcode_t *dest), ARGIN(Parrot_Context * old_ctx), ...)
+static void
+pass_exception_args(PARROT_INTERP, ARGIN(const char *sig), ...)
 {
     ASSERT_ARGS(pass_exception_args)
-    va_list   ap;
-    opcode_t *next;
+    va_list  args;
+    PMC     *sig_obj;
+
+    va_start(args, sig);
+    sig_obj = Parrot_pcc_build_sig_object_from_varargs(interp, PMCNULL, sig, args);
+    va_end(args);
 
-    va_start(ap, old_ctx);
-    next = parrot_pass_args_fromc(interp, sig, dest, old_ctx, ap);
-    va_end(ap);
+    CALLSIGNATURE_is_exception_SET(sig_obj);
 
-    return next;
+    CONTEXT(interp)->current_sig             = sig_obj;
 }
 
 /*
@@ -391,6 +372,7 @@
      * XXX TT#596 - pass in current context instead when we have context PMCs. */
     VTABLE_set_attr_str(interp, exception, CONST_STRING(interp, "thrower"), CONTEXT(interp)->current_cont);
 
+
     /* it's a C exception handler */
     if (PObj_get_FLAGS(handler) & SUB_FLAG_C_HANDLER) {
         Parrot_runloop * const jump_point =
@@ -400,11 +382,10 @@
 
     /* Run the handler. */
     address = VTABLE_invoke(interp, handler, NULL);
-    if (PMC_cont(handler)->current_results)
-        address = pass_exception_args(interp, "P", address,
-                CONTEXT(interp), exception);
+    pass_exception_args(interp, "P", exception);
     PARROT_ASSERT(return_point->handler_start == NULL);
     return_point->handler_start = address;
+
     longjmp(return_point->resume, 2);
 }
 


More information about the parrot-commits mailing list