Skip to content
Browse files

add function Parrot_ext_try and use it in extend_vtable tests

  • Loading branch information...
1 parent 09dc23b commit 668635fbd9301cca2ec1b8e762349fb2c0d653ae @NotFound NotFound committed
Showing with 79 additions and 4 deletions.
  1. +12 −0 include/parrot/extend.h
  2. +40 −0 src/extend.c
  3. +27 −4 t/src/extend_vtable.t
View
12 include/parrot/extend.h
@@ -71,6 +71,16 @@ void Parrot_ext_call(PARROT_INTERP,
__attribute__nonnull__(3);
PARROT_EXPORT
+void Parrot_ext_try(PARROT_INTERP,
+ ARGIN_NULLOK(void (*cfunction)(Parrot_Interp,
+ void *)),
+ ARGIN_NULLOK(void (*chandler)(Parrot_Interp,
+ PMC *,
+ void *)),
+ ARGIN_NULLOK(void *data))
+ __attribute__nonnull__(1);
+
+PARROT_EXPORT
PARROT_PURE_FUNCTION
PARROT_WARN_UNUSED_RESULT
Parrot_Language Parrot_find_language(SHIM_INTERP,
@@ -201,6 +211,8 @@ int Parrot_vfprintf(PARROT_INTERP,
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(sub_pmc) \
, PARROT_ASSERT_ARG(signature))
+#define ASSERT_ARGS_Parrot_ext_try __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_find_language __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_Parrot_fprintf __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
View
40 src/extend.c
@@ -326,6 +326,46 @@ Parrot_ext_call(PARROT_INTERP, ARGIN(Parrot_PMC sub_pmc),
Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_call_obj);
}
+/*
+
+=item C<void Parrot_ext_try(PARROT_INTERP, void (*cfunction(Parrot_Interp, void
+*)), void (*chandler(Parrot_Interp, PMC *, void *)), void *data)>
+
+Executes the cfunction argument wrapped in a exception handler.
+If the function throws, the provided handler function is invoked
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_ext_try(PARROT_INTERP,
+ ARGIN_NULLOK(void (*cfunction)(Parrot_Interp, void *)),
+ ARGIN_NULLOK(void (*chandler)(Parrot_Interp, PMC *, void *)),
+ ARGIN_NULLOK(void *data))
+{
+ ASSERT_ARGS(Parrot_ext_try)
+ if (cfunction) {
+ Parrot_runloop jmp;
+ PARROT_CALLIN_START(interp);
+ switch (setjmp(jmp.resume)) {
+ case 0: /* try */
+ Parrot_ex_add_c_handler(interp, &jmp);
+ (*cfunction)(interp, data);
+ Parrot_cx_delete_handler_local(interp, STRINGNULL);
+ break;
+ default: /* catch */
+ {
+ PMC *exception = jmp.exception;
+ Parrot_cx_delete_handler_local(interp, STRINGNULL);
+ if (chandler)
+ (*chandler)(interp, exception, data);
+ }
+ }
+ PARROT_CALLIN_END(interp);
+ }
+}
/*
View
31 t/src/extend_vtable.t
@@ -46,6 +46,7 @@ my $common = linedirective(__LINE__) . <<'CODE';
static void fail(const char *msg);
static Parrot_String createstring(Parrot_Interp interp, const char * value);
static Parrot_Interp new_interp();
+static void handler(Parrot_Interp interp, Parrot_PMC exception, void *unused);
static void fail(const char *msg)
{
@@ -66,6 +67,24 @@ static Parrot_Interp new_interp()
return interp;
}
+static void handler(Parrot_Interp interp, Parrot_PMC exception, void *unused)
+{
+ Parrot_printf(interp, "Failed!\n");
+ if (exception) {
+ Parrot_String key;
+ Parrot_Int type;
+ Parrot_Int severity;
+ Parrot_String message;
+
+ key = createstring(interp, "type");
+ type = Parrot_PMC_get_integer_keyed_str(interp, exception, key);
+ key = createstring(interp, "severity");
+ severity = Parrot_PMC_get_integer_keyed_str(interp, exception, key);
+ message = Parrot_PMC_get_string(interp, exception);
+ Parrot_printf(interp, "Exception is: type %d severity %d message '%Ss'\n",
+ type, severity, message);
+ }
+}
CODE
@@ -74,9 +93,8 @@ sub extend_vtable_output_is
my ($code, $expected_output, $msg, @opts) = @_;
c_output_is(
$common . linedirective(__LINE__) . <<CODE,
-int main(void)
+int dotest(Parrot_Interp interp, void *unused)
{
- Parrot_Interp interp;
Parrot_PMC pmc, pmc2, pmc3, pmc_string, pmc_string2;
Parrot_PMC pmc_float, pmc_float2;
Parrot_PMC rpa, rpa2;
@@ -84,8 +102,6 @@ int main(void)
Parrot_Float number, number2;
Parrot_String string, string2;
- interp = new_interp();
-
type = Parrot_PMC_typenum(interp, "Integer");
rpa = Parrot_PMC_new(interp, Parrot_PMC_typenum(interp, "ResizablePMCArray"));
rpa2 = Parrot_PMC_new(interp, Parrot_PMC_typenum(interp, "ResizablePMCArray"));
@@ -106,6 +122,13 @@ $code
Parrot_destroy(interp);
printf("Done!\\n");
+}
+
+int main(void)
+{
+ Parrot_Interp interp;
+ interp = new_interp();
+ Parrot_ext_try(interp, &dotest, &handler, NULL);
return 0;
}
CODE

0 comments on commit 668635f

Please sign in to comment.
Something went wrong with that request. Please try again.