Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
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...
commit 2483c6885910577821531e8da67f2f0c00f26775 1 parent b50f1fc
@Whiteknight Whiteknight authored
View
22 include/parrot/api.h
@@ -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 = (\
View
10 include/parrot/debugger.h
@@ -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) \
View
8 include/parrot/exit.h
@@ -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))
View
15 include/parrot/global_setup.h
@@ -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 = (\
View
7 include/parrot/hll.h
@@ -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))
View
4 include/parrot/interpreter.h
@@ -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
77 src/debug.c
@@ -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
28 src/embed/api.c
@@ -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
4 src/embed/strings.c
@@ -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);
}
View
20 src/exceptions.c
@@ -99,22 +99,19 @@ die_from_exception(PARROT_INTERP, ARGIN(PMC *exception))
STRING * const message = already_dying ? STRINGNULL :
VTABLE_get_string(interp, exception);
- INTVAL exit_status = 1;
const INTVAL severity = already_dying ? EXCEPT_fatal :
VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "severity"));
- interp->final_error = message;
- if (already_dying) {
- //fflush(stderr);
- //fprintf(stderr, "\n***FATAL ERROR: Exception thrown while dying from previous unhandled Exception\n");
- Parrot_x_exit(interp, EXCEPT_fatal);
- }
+ if (already_dying)
+ Parrot_x_jump_out(interp, 1);
else {
/* In some cases we have a fatal exception before the IO system
* is completely initialized. Do some attempt to output the
* message to stderr, to help diagnosing. */
const int use_perr = !PMC_IS_NULL(Parrot_io_STDERR(interp));
already_dying = 1;
+ interp->final_exception = exception;
+ interp->exit_code = 1;
/* flush interpreter output to get things printed in order */
if (!PMC_IS_NULL(Parrot_io_STDOUT(interp)))
@@ -146,7 +143,7 @@ die_from_exception(PARROT_INTERP, ARGIN(PMC *exception))
}
else if (severity == EXCEPT_exit) {
/* TODO: get exit status based on type */
- exit_status = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "exit_code"));
+ interp->exit_code = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "exit_code"));
}
else {
Parrot_io_eprintf(interp, "No exception handler and no message\n");
@@ -168,12 +165,7 @@ die_from_exception(PARROT_INTERP, ARGIN(PMC *exception))
if (interp->thread_data && interp->thread_data->tid)
pt_thread_detach(interp->thread_data->tid);
- /*
- * only main should run the destroy functions - exit handler chain
- * is freed during Parrot_x_exit
- */
- interp->final_error = message;
- Parrot_x_exit(interp, exit_status);
+ Parrot_x_jump_out(interp, 1);
}
/*
View
21 src/exit.c
@@ -64,6 +64,20 @@ PARROT_EXPORT
PARROT_DOES_NOT_RETURN
PARROT_COLD
void
+Parrot_x_jump_out(PARROT_INTERP, int status)
+{
+ ASSERT_ARGS(Parrot_x_jump_out)
+
+ if (interp->api_jmp_buf)
+ longjmp(*(interp->api_jmp_buf), 1);
+ else
+ exit(status);
+}
+
+PARROT_EXPORT
+PARROT_DOES_NOT_RETURN
+PARROT_COLD
+void
Parrot_x_exit(PARROT_INTERP, int status)
{
ASSERT_ARGS(Parrot_x_exit)
@@ -94,12 +108,7 @@ Parrot_x_exit(PARROT_INTERP, int status)
}
interp->exit_handler_list = NULL;
- interp->exit_code = status;
-
- if (interp->api_jmp_buf)
- longjmp(*(interp->api_jmp_buf), 1);
- else
- exit(status);
+ Parrot_x_jump_out(interp, status);
}
/*
View
3  src/gc/mark_sweep.c
@@ -222,6 +222,9 @@ Parrot_gc_trace_root(PARROT_INTERP,
/* Walk the iodata */
Parrot_IOData_mark(interp, interp->piodata);
+ if (!PMC_IS_NULL(interp->final_exception))
+ Parrot_gc_mark_PMC_alive(interp, interp->final_exception);
+
if (trace == GC_TRACE_FULL)
trace_system_areas(interp, mem_pools);
View
10 src/global_setup.c
@@ -39,17 +39,17 @@ static PMC * parrot_config_hash_global = NULL;
/* HEADERIZER BEGIN: static */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-static void Parrot_gbl_setup_2(PARROT_INTERP)
+static void Parrot_gbl_set_config_hash_interpreter(PARROT_INTERP)
__attribute__nonnull__(1);
-static void Parrot_gbl_set_config_hash_interpreter(PARROT_INTERP)
+static void Parrot_gbl_setup_2(PARROT_INTERP)
__attribute__nonnull__(1);
-#define ASSERT_ARGS_Parrot_gbl_setup_2 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
- PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_gbl_set_config_hash_interpreter \
__attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_Parrot_gbl_setup_2 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: static */
@@ -70,7 +70,7 @@ void
Parrot_gbl_set_config_hash_internal(ARGIN(const unsigned char* parrot_config),
unsigned int parrot_config_size)
{
- ASSERT_ARGS(Parrot_set_config_hash_internal)
+ ASSERT_ARGS(Parrot_gbl_set_config_hash_internal)
if (parrot_config_stored != NULL) {
parrot_config_stored = parrot_config;
parrot_config_size_stored = parrot_config_size;
View
44 src/main.c
@@ -24,14 +24,11 @@ Start Parrot
#include "parrot/longopt.h"
#include "parrot/api.h"
-
-
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-static void show_last_error_and_exit(Parrot_PMC interp);
static void help(void);
static void help_debug(void);
PARROT_WARN_UNUSED_RESULT
@@ -72,11 +69,16 @@ static void parseflags_minimal(
__attribute__nonnull__(3)
FUNC_MODIFIES(* initargs);
+static void print_parrot_string(
+ Parrot_PMC interp,
+ FILE *vector,
+ Parrot_String str);
+
+static void show_last_error_and_exit(Parrot_PMC interp);
static void usage(ARGMOD(FILE *fp))
__attribute__nonnull__(1)
FUNC_MODIFIES(*fp);
-#define ASSERT_ARGS_show_last_error_and_exit __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_help __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_help_debug __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_is_all_digits __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -93,6 +95,8 @@ static void usage(ARGMOD(FILE *fp))
#define ASSERT_ARGS_parseflags_minimal __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(initargs) \
, PARROT_ASSERT_ARG(argv))
+#define ASSERT_ARGS_print_parrot_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+#define ASSERT_ARGS_show_last_error_and_exit __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_usage __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(fp))
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
@@ -163,23 +167,35 @@ main(int argc, const char *argv[])
static void
show_last_error_and_exit(Parrot_PMC interp)
{
- Parrot_String errmsg;
- Parrot_Int exit_code;
- Parrot_Int is_error;
- if (!Parrot_api_get_result(interp, &is_error, &exit_code, &errmsg)){
+ Parrot_String errmsg, backtrace;
+ Parrot_Int exit_code, is_error;
+ Parrot_PMC exception;
+
+ if (!(Parrot_api_get_result(interp, &is_error, &exception, &exit_code, &errmsg) &&
+ Parrot_api_get_exception_backtrace(interp, exception, &backtrace))) {
fprintf(stderr, "PARROT VM: Cannot recover\n");
exit(EXIT_FAILURE);
}
- /* if (errmsg) { */
- /* char * errmsg_raw; */
- /* Parrot_api_string_export_ascii(interp, errmsg, &errmsg_raw); */
- /* fprintf(stderr, "PARROT VM: %s\n", errmsg_raw); */
- /* Parrot_api_string_free_exported_ascii(interp, errmsg_raw); */
- /* } */
+ print_parrot_string(interp, stderr, errmsg);
+ print_parrot_string(interp, stderr, backtrace);
+
exit(exit_code);
}
+static void
+print_parrot_string(Parrot_PMC interp, FILE *vector, Parrot_String str)
+{
+ char * msg_raw;
+ if (!str)
+ return;
+ Parrot_api_string_export_ascii(interp, str, &msg_raw);
+ if (msg_raw) {
+ fprintf(vector, "%s\n", msg_raw);
+ Parrot_api_string_free_exported_ascii(interp, msg_raw);
+ }
+}
+
/*
=item C<static int is_all_digits(const char *s)>
View
16 src/pbc_disassemble.c
@@ -151,10 +151,12 @@ main(int argc, const char *argv[])
static void
show_last_error_and_exit(Parrot_PMC interp)
{
- Parrot_String errmsg;
- Parrot_Int exit_code;
- Parrot_Int is_error;
- if (!Parrot_api_get_result(interp, &is_error, &exit_code, &errmsg)){
+ Parrot_String errmsg, backtrace;
+ Parrot_Int exit_code, is_error;
+ Parrot_PMC exception;
+
+ if (!(Parrot_api_get_result(interp, &is_error, &exception, &exit_code, &errmsg) &&
+ Parrot_api_get_exception_backtrace(interp, exception, &backtrace))) {
fprintf(stderr, "PARROT VM: Cannot recover\n");
exit(EXIT_FAILURE);
}
@@ -162,7 +164,11 @@ show_last_error_and_exit(Parrot_PMC interp)
if (errmsg) {
char * errmsg_raw;
Parrot_api_string_export_ascii(interp, errmsg, &errmsg_raw);
- fprintf(stderr, "PARROT VM: %s\n", errmsg_raw);
+ fprintf(stderr, "%s\n", errmsg_raw);
+ Parrot_api_string_free_exported_ascii(interp, errmsg_raw);
+
+ Parrot_api_string_export_ascii(interp, backtrace, &errmsg_raw);
+ fprintf(stderr, "%s\n", errmsg_raw);
Parrot_api_string_free_exported_ascii(interp, errmsg_raw);
}
exit(exit_code);
View
16 tools/dev/pbc_to_exe.pir
@@ -114,10 +114,12 @@ HEADER
static void
show_last_error_and_exit(Parrot_PMC interp)
{
- Parrot_String errmsg;
- Parrot_Int exit_code;
- Parrot_Int is_error;
- if (!Parrot_api_get_result(interp, &is_error, &exit_code, &errmsg)){
+ Parrot_String errmsg, backtrace;
+ Parrot_Int exit_code, is_error;
+ Parrot_PMC exception;
+
+ if (!(Parrot_api_get_result(interp, &is_error, &exception, &exit_code, &errmsg) &&
+ Parrot_api_get_exception_backtrace(interp, exception, &backtrace))) {
fprintf(stderr, "PARROT VM: Cannot recover\n");
exit(EXIT_FAILURE);
}
@@ -125,7 +127,11 @@ HEADER
if (errmsg) {
char * errmsg_raw;
Parrot_api_string_export_ascii(interp, errmsg, &errmsg_raw);
- fprintf(stderr, "PARROT VM: %s\n", errmsg_raw);
+ fprintf(stderr, "%s\n", errmsg_raw);
+ Parrot_api_string_free_exported_ascii(interp, errmsg_raw);
+
+ Parrot_api_string_export_ascii(interp, backtrace, &errmsg_raw);
+ fprintf(stderr, "%s\n", errmsg_raw);
Parrot_api_string_free_exported_ascii(interp, errmsg_raw);
}
exit(exit_code);

0 comments on commit 2483c68

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