cvsuser 03/10/23 08:03:37
Modified: classes exception_handler.pmc
. exceptions.c
include/parrot exceptions.h
t/src extend.t
Log:
catch a PASM exception in C code
Revision Changes Path
1.6 +4 -3 parrot/classes/exception_handler.pmc
Index: exception_handler.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/exception_handler.pmc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -r1.5 -r1.6
--- exception_handler.pmc 25 Aug 2003 09:46:23 -0000 1.5
+++ exception_handler.pmc 23 Oct 2003 15:03:30 -0000 1.6
@@ -1,7 +1,7 @@
/* exception_handler.pmc
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: exception_handler.pmc,v 1.5 2003/08/25 09:46:23 leo Exp $
+ * $Id: exception_handler.pmc,v 1.6 2003/10/23 15:03:30 leo Exp $
* Overview:
* This is the exception_handler class
* Data Structure and Algorithms:
@@ -19,8 +19,9 @@
pmclass Exception_Handler extends Continuation {
- INTVAL type() { /* pmc2c.pl doesn't like empty classes */
- return SELF->vtable->base_type;
+ void init() {
+ PObj_get_FLAGS(SELF) &= ~PObj_private0_FLAG;
+ SUPER();
}
}
1.38 +25 -1 parrot/exceptions.c
Index: exceptions.c
===================================================================
RCS file: /cvs/public/parrot/exceptions.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -w -r1.37 -r1.38
--- exceptions.c 15 Oct 2003 08:31:20 -0000 1.37
+++ exceptions.c 23 Oct 2003 15:03:33 -0000 1.38
@@ -1,7 +1,7 @@
/* exceptions.c
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: exceptions.c,v 1.37 2003/10/15 08:31:20 leo Exp $
+ * $Id: exceptions.c,v 1.38 2003/10/23 15:03:33 leo Exp $
* Overview:
* define the internal interpreter exceptions
* Data Structure and Algorithms:
@@ -159,6 +159,21 @@
STACK_ENTRY_PMC);
}
+/*
+ * generate an exception handler, that catches PASM level exceptions
+ * inside a C function
+ * This could be a separate class too, for now just a private flag
+ * bit is set
+ */
+PMC*
+new_c_exception_handler(Parrot_Interp interpreter, Parrot_exception *jb)
+{
+ PMC *handler = pmc_new(interpreter, enum_class_Exception_Handler);
+ PObj_get_FLAGS(handler) |= PObj_private0_FLAG;
+ handler->cache.struct_val = jb;
+ return handler;
+}
+
void *
throw_exception(Parrot_Interp interpreter, PMC *exception, void *dest)
{
@@ -183,6 +198,15 @@
restore_context(interpreter, &cc->ctx);
/* put exception object in P5 */
REG_PMC(5) = exception;
+ if (PObj_get_FLAGS(handler) & PObj_private0_FLAG) {
+ /* its a C exception handler */
+ Parrot_exception *jb = (Parrot_exception *) handler->cache.struct_val;
+#ifdef PARROT_HAS_HEADER_SETJMP
+ longjmp(jb->destination, 1);
+#else
+ return NULL; /* we are lost */
+#endif
+ }
/* return the address of the handler */
return handler->cache.struct_val;
}
1.39 +4 -1 parrot/include/parrot/exceptions.h
Index: exceptions.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/exceptions.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -w -r1.38 -r1.39
--- exceptions.h 29 Aug 2003 11:30:19 -0000 1.38
+++ exceptions.h 23 Oct 2003 15:03:35 -0000 1.39
@@ -1,7 +1,7 @@
/* exceptions.h
* Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
* CVS Info
- * $Id: exceptions.h,v 1.38 2003/08/29 11:30:19 leo Exp $
+ * $Id: exceptions.h,v 1.39 2003/10/23 15:03:35 leo Exp $
* Overview:
* define the internal interpreter exceptions
* Data Structure and Algorithms:
@@ -101,6 +101,9 @@
size_t handle_exception(Parrot_Interp);
void do_exception(exception_severity severity, long error);
+
+PMC* new_c_exception_handler(Parrot_Interp, Parrot_exception *jb);
+
#endif
/*
1.7 +56 -1 parrot/t/src/extend.t
Index: extend.t
===================================================================
RCS file: /cvs/public/parrot/t/src/extend.t,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -w -r1.6 -r1.7
--- extend.t 22 Oct 2003 08:07:09 -0000 1.6
+++ extend.t 23 Oct 2003 15:03:37 -0000 1.7
@@ -1,7 +1,7 @@
#! perl -w
# Tests the extension API
-use Parrot::Test tests => 11;
+use Parrot::Test tests => 12;
use Parrot::Config;
c_output_is(<<'CODE', <<'OUTPUT', "set/get_intreg");
@@ -378,6 +378,61 @@
back
OUTPUT
+open S, ">$temp.pasm" or die "Can't write $temp.pasm";
+print S <<'EOF';
+ .pcc_sub _sub1:
+ printerr "in sub1\n"
+ new_pad 0
+ find_lex P2, "no_such_var"
+ printerr "never\n"
+ invoke P1
+EOF
+close S;
+# compile to pbc
+system(".$PConfig{slash}parrot$PConfig{exe} -o $temp.pbc $temp.pasm");
+
+c_output_is(<<'CODE', <<'OUTPUT', "call a parrot sub");
+
+#include <stdio.h>
+/* have to cheat because of missing extend interfaces */
+/* #include "parrot/extend.h" */
+#include "parrot/parrot.h"
+#include "parrot/embed.h"
+
+/* also both the test PASM and main print to stderr
+ * so that buffering in PIO isn't and issue
+ */
+
+int main(int argc, char* argv[]) {
+ Parrot_Interp interpreter;
+ struct PackFile *pf;
+ PMC *key, *sub, *arg;
+ Parrot_exception jb;
+
+ interpreter = Parrot_new();
+ pf = Parrot_readbc(interpreter, "temp.pbc");
+ Parrot_loadbc(interpreter, pf);
+ key = key_new_cstring(interpreter, "_sub1");
+ sub = VTABLE_get_pmc_keyed(interpreter,
+ interpreter->perl_stash->stash_hash, key);
+ if (setjmp(jb.destination)) {
+ fprintf(stderr, "caught\n");
+ }
+ else {
+ PMC *handler = new_c_exception_handler(interpreter, &jb);
+ push_exception(interpreter, handler);
+ Parrot_call(interpreter, sub, 0);
+ }
+ fprintf(stderr, "back\n");
+ return 0;
+}
+CODE
+in sub1
+caught
+back
+OUTPUT
+
unlink "$temp.pasm", "$temp.pbc";
+
1;