Permalink
Browse files

implement the new error-handling mechanism. Instead of a string, we p…

…ass out the raw exception object for the embedder to query. Add some helper API functions. Parrot_x_exit should now only be called when actually exiting. For most operations, we should call the new Parrot_x_jump_out instead
  • Loading branch information...
1 parent b50f1fc commit 2483c6885910577821531e8da67f2f0c00f26775 @Whiteknight Whiteknight committed Dec 3, 2010
View
@@ -14,7 +14,6 @@
#include "parrot/config.h"
#include "parrot/core_types.h"
-
#define PARROT_API PARROT_EXPORT
/* having a modified version of PARROT_ASSERT which resolves as an integer
@@ -129,17 +128,32 @@ Parrot_Int Parrot_api_flag(
FUNC_MODIFIES(*interp_pmc);
PARROT_API
+Parrot_Int Parrot_api_get_exception_backtrace(
+ ARGMOD(PMC * interp_pmc),
+ ARGMOD(PMC * exception),
+ ARGOUT(Parrot_String ** bt))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ FUNC_MODIFIES(* interp_pmc)
+ FUNC_MODIFIES(* exception)
+ FUNC_MODIFIES(* bt);
+
+PARROT_API
Parrot_Int Parrot_api_get_result(
ARGMOD(PMC * interp_pmc),
ARGOUT(Parrot_Int *is_error),
+ ARGOUT(PMC ** exception),
ARGOUT(Parrot_Int *exit_code),
ARGOUT(Parrot_String * errmsg))
__attribute__nonnull__(1)
__attribute__nonnull__(2)
__attribute__nonnull__(3)
__attribute__nonnull__(4)
+ __attribute__nonnull__(5)
FUNC_MODIFIES(* interp_pmc)
FUNC_MODIFIES(*is_error)
+ FUNC_MODIFIES(* exception)
FUNC_MODIFIES(*exit_code)
FUNC_MODIFIES(* errmsg);
@@ -262,9 +276,15 @@ Parrot_Int Parrot_api_set_warnings(
, PARROT_ASSERT_ARG(outfile))
#define ASSERT_ARGS_Parrot_api_flag __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp_pmc))
+#define ASSERT_ARGS_Parrot_api_get_exception_backtrace \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp_pmc) \
+ , PARROT_ASSERT_ARG(exception) \
+ , PARROT_ASSERT_ARG(bt))
#define ASSERT_ARGS_Parrot_api_get_result __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp_pmc) \
, PARROT_ASSERT_ARG(is_error) \
+ , PARROT_ASSERT_ARG(exception) \
, PARROT_ASSERT_ARG(exit_code) \
, PARROT_ASSERT_ARG(errmsg))
#define ASSERT_ARGS_Parrot_api_get_runtime_path __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -223,6 +223,12 @@ void PDB_script_file(PARROT_INTERP, ARGIN(const char *command))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+STRING * Parrot_dbg_get_exception_backtrace(PARROT_INTERP,
+ ARGMOD(PMC * exception))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(* exception);
+
long PDB_add_label(PARROT_INTERP,
ARGMOD(PDB_file_t *file),
ARGIN(const opcode_t *cur_opcode),
@@ -385,6 +391,10 @@ void PDB_watchpoint(PARROT_INTERP, ARGIN(const char *command))
#define ASSERT_ARGS_PDB_script_file __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(command))
+#define ASSERT_ARGS_Parrot_dbg_get_exception_backtrace \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(exception))
#define ASSERT_ARGS_PDB_add_label __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(file) \
@@ -32,6 +32,12 @@ void Parrot_x_exit(PARROT_INTERP, int status)
__attribute__nonnull__(1);
PARROT_EXPORT
+PARROT_DOES_NOT_RETURN
+PARROT_COLD
+void Parrot_x_jump_out(PARROT_INTERP, int status)
+ __attribute__nonnull__(1);
+
+PARROT_EXPORT
void Parrot_x_on_exit(PARROT_INTERP,
ARGIN(exit_handler_f function),
ARGIN_NULLOK(void *arg))
@@ -40,6 +46,8 @@ void Parrot_x_on_exit(PARROT_INTERP,
#define ASSERT_ARGS_Parrot_x_exit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_Parrot_x_jump_out __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_x_on_exit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(function))
@@ -25,21 +25,16 @@ void Parrot_gbl_initialize_core_pmcs(PARROT_INTERP, int pass)
/* HEADERIZER BEGIN: src/global_setup.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-PARROT_EXPORT
-void Parrot_gbl_set_config_hash_internal(
- ARGIN(const unsigned char* parrot_config),
- unsigned int parrot_config_size)
- __attribute__nonnull__(1);
-
void init_world(PARROT_INTERP)
__attribute__nonnull__(1);
void Parrot_gbl_init_world_once(PARROT_INTERP)
__attribute__nonnull__(1);
-#define ASSERT_ARGS_Parrot_gbl_set_config_hash_internal \
- __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(parrot_config))
+void Parrot_gbl_set_config_hash_internal(
+ ARGIN(const unsigned char* parrot_config),
+ unsigned int parrot_config_size)
+ __attribute__nonnull__(1);
void Parrot_set_config_hash_pmc(PARROT_INTERP, ARGMOD(PMC * config))
__attribute__nonnull__(1)
@@ -50,7 +45,7 @@ void Parrot_set_config_hash_pmc(PARROT_INTERP, ARGMOD(PMC * config))
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_gbl_init_world_once __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_Parrot_set_config_hash_internal \
+#define ASSERT_ARGS_Parrot_gbl_set_config_hash_internal \
__attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(parrot_config))
#define ASSERT_ARGS_Parrot_set_config_hash_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -52,7 +52,9 @@ PMC* Parrot_hll_get_HLL_namespace(PARROT_INTERP, int hll_id)
__attribute__nonnull__(1);
PARROT_EXPORT
-INTVAL Parrot_hll_get_HLL_type(PARROT_INTERP, INTVAL hll_id, INTVAL core_type)
+INTVAL Parrot_hll_get_HLL_type(PARROT_INTERP,
+ INTVAL hll_id,
+ INTVAL core_type)
__attribute__nonnull__(1);
PARROT_EXPORT
@@ -74,7 +76,8 @@ void Parrot_hll_register_HLL_type(PARROT_INTERP,
void Parrot_hll_init_HLL(PARROT_INTERP)
__attribute__nonnull__(1);
-#define ASSERT_ARGS_Parrot_hll_get_ctx_HLL_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_Parrot_hll_get_ctx_HLL_namespace \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_hll_get_ctx_HLL_type __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
@@ -267,8 +267,8 @@ struct parrot_interp_t {
* inside the invoke these get moved to the context structure */
PMC *current_cont; /* the return continuation PMC */
Parrot_jump_buff *api_jmp_buf; /* jmp point out of Parrot */
- STRING * final_error; /* string to hold the final error message */
- Parrot_Int exit_code;
+ PMC * final_exception; /* Final exception PMC */
+ INTVAL exit_code;
};
/* typedef struct parrot_interp_t Interp; done in parrot.h so that
View
@@ -122,6 +122,15 @@ static void no_such_register(PARROT_INTERP,
UINTVAL register_num)
__attribute__nonnull__(1);
+static STRING * PDB_get_continuation_backtrace(PARROT_INTERP,
+ ARGMOD(PMC * sub),
+ ARGMOD(PMC * ctx))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3)
+ FUNC_MODIFIES(* sub)
+ FUNC_MODIFIES(* ctx);
+
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
PARROT_PURE_FUNCTION
@@ -155,6 +164,11 @@ static const char * skip_whitespace(ARGIN(const char *cmd))
PARROT_ASSERT_ARG(pdb))
#define ASSERT_ARGS_no_such_register __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_PDB_get_continuation_backtrace \
+ __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(sub) \
+ , PARROT_ASSERT_ARG(ctx))
#define ASSERT_ARGS_skip_whitespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(cmd))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
@@ -3242,6 +3256,25 @@ PDB_help(PARROT_INTERP, ARGIN(const char *command))
}
}
+STRING *
+Parrot_dbg_get_exception_backtrace(PARROT_INTERP, ARGMOD(PMC * exception))
+{
+ ASSERT_ARGS(PDB_backtrace)
+ STRING *str;
+ PMC *old = PMCNULL;
+ int rec_level = 0;
+ int limit_count = 0;
+
+ PMC * resume = VTABLE_get_attr_str(interp, exception, CONST_STRING(interp, "resume"));
+ if (PMC_IS_NULL(resume))
+ return STRINGNULL;
+ else {
+ const Parrot_Continuation_attributes * const cont = PARROT_CONTINUATION(resume);
+ STRING * const bt = PDB_get_continuation_backtrace(interp, PMCNULL, cont->to_ctx);
+ return bt;
+ }
+}
+
/*
=item C<void PDB_backtrace(PARROT_INTERP)>
@@ -3257,19 +3290,27 @@ void
PDB_backtrace(PARROT_INTERP)
{
ASSERT_ARGS(PDB_backtrace)
- STRING *str;
- PMC *old = PMCNULL;
- int rec_level = 0;
- int limit_count = 0;
-
/* information about the current sub */
PMC *sub = interpinfo_p(interp, CURRENT_SUB);
PMC *ctx = CURRENT_CONTEXT(interp);
+ STRING * const bt = PDB_get_continuation_backtrace(interp, sub, ctx);
+ Parrot_io_eprintf(interp, "%Ss", bt);
+}
+
+static STRING *
+PDB_get_continuation_backtrace(PARROT_INTERP, ARGMOD(PMC * sub), ARGMOD(PMC * ctx))
+{
+ ASSERT_ARGS(PDB_get_continuation_backtrace)
+ STRING *str;
+ PMC *old = PMCNULL;
+ PMC *output = Parrot_pmc_new(interp, enum_class_StringBuilder);
+ int rec_level = 0;
+ int limit_count = 0;
if (!PMC_IS_NULL(sub)) {
str = Parrot_Context_infostr(interp, ctx);
if (str) {
- Parrot_io_eprintf(interp, "%Ss", str);
+ VTABLE_push_string(interp, output, str);
if (interp->code->annotations) {
PMC *annot = PackFile_Annotations_lookup(interp, interp->code->annotations,
Parrot_pcc_get_pc(interp, ctx) - interp->code->base.data + 1, NULL);
@@ -3279,13 +3320,14 @@ PDB_backtrace(PARROT_INTERP)
PMC *pline = VTABLE_get_pmc_keyed_str(interp, annot,
Parrot_str_new_constant(interp, "line"));
if ((!PMC_IS_NULL(pfile)) && (!PMC_IS_NULL(pline))) {
- STRING *file = VTABLE_get_string(interp, pfile);
+ STRING * const file = VTABLE_get_string(interp, pfile);
INTVAL line = VTABLE_get_integer(interp, pline);
- Parrot_io_eprintf(interp, " (%Ss:%li)", file, (long)line);
+ STRING * const fmt = Parrot_sprintf_c(interp, " (%Ss:%li)", file, (long)line);
+ VTABLE_push_string(interp, output, fmt);
}
}
}
- Parrot_io_eprintf(interp, "\n");
+ VTABLE_push_string(interp, output, CONST_STRING(interp, "\n"));
}
}
@@ -3328,7 +3370,8 @@ PDB_backtrace(PARROT_INTERP)
++rec_level;
}
else if (rec_level != 0) {
- Parrot_io_eprintf(interp, "... call repeated %d times\n", rec_level);
+ STRING * const fmt = Parrot_sprintf_c(interp, "... call repeated %d times\n", rec_level);
+ VTABLE_push_string(interp, output, fmt);
rec_level = 0;
}
@@ -3349,11 +3392,12 @@ PDB_backtrace(PARROT_INTERP)
if ((!PMC_IS_NULL(pfile)) && (!PMC_IS_NULL(pline))) {
STRING *file = VTABLE_get_string(interp, pfile);
INTVAL line = VTABLE_get_integer(interp, pline);
- Parrot_io_eprintf(interp, " (%Ss:%li)", file, (long)line);
+ STRING * const fmt = Parrot_sprintf_c(interp, " (%Ss:%li)", file, (long)line);
+ VTABLE_push_string(interp, output, fmt);
}
}
}
- Parrot_io_eprintf(interp, "\n");
+ VTABLE_push_string(interp, output, CONST_STRING(interp, "\n"));
}
/* get the next Continuation */
@@ -3364,10 +3408,15 @@ PDB_backtrace(PARROT_INTERP)
break;
}
- if (rec_level != 0)
- Parrot_io_eprintf(interp, "... call repeated %d times\n", rec_level);
+ if (rec_level != 0) {
+ STRING * const fmt = Parrot_sprintf_c(interp, "... call repeated %d times\n", rec_level);
+ VTABLE_push_string(interp, output, fmt);
+ }
+ return VTABLE_get_string(interp, output);
}
+
+
/*
* GDB functions
*
View
@@ -9,15 +9,33 @@
PARROT_API
Parrot_Int
Parrot_api_get_result(ARGMOD(PMC * interp_pmc), ARGOUT(Parrot_Int *is_error),
+ ARGOUT(PMC ** exception),
ARGOUT(Parrot_Int *exit_code), ARGOUT(Parrot_String * errmsg))
{
- EMBED_API_CALLIN(interp_pmc, interp);
+ EMBED_API_CALLIN(interp_pmc, interp)
*exit_code = interp->exit_code;
- *errmsg = interp->final_error;
- *is_error = !interp->exit_code && *errmsg;
- interp->final_error = NULL;
+ *exception = interp->final_exception;
+ if (PMC_IS_NULL(exception)) {
+ *is_error = 0;
+ *errmsg = STRINGNULL;
+ } else {
+ *is_error = !interp->exit_code;
+ *errmsg = VTABLE_get_string(interp, *exception);
+ }
+ // TODO: GC mark interp->final_exception
+ interp->final_exception = PMCNULL;
interp->exit_code = 0;
- EMBED_API_CALLOUT(interp_pmc, interp);
+ EMBED_API_CALLOUT(interp_pmc, interp)
+}
+
+PARROT_API
+Parrot_Int
+Parrot_api_get_exception_backtrace(ARGMOD(PMC * interp_pmc), ARGMOD(PMC * exception), ARGOUT(Parrot_String ** bt))
+{
+ EMBED_API_CALLIN(interp_pmc, interp)
+ STRING * const bts = Parrot_dbg_get_exception_backtrace(interp, exception);
+ *bt = bts;
+ EMBED_API_CALLOUT(interp_pmc, interp)
}
PARROT_API
View
@@ -11,7 +11,9 @@ Parrot_api_string_export_ascii(Parrot_PMC interp_pmc, ARGIN(Parrot_String string
//ASSERT_ARGS(Parrot_api_string_export)
EMBED_API_CALLIN(interp_pmc, interp);
if(!STRING_IS_NULL(string))
- *strout = Parrot_str_to_cstring(interp, string);
+ *strout = Parrot_str_to_cstring(interp, string);
+ else
+ *strout = NULL;
EMBED_API_CALLOUT(interp_pmc, interp);
}
Oops, something went wrong. Retry.

0 comments on commit 2483c68

Please sign in to comment.