Skip to content
This repository
Browse code

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
Andrew Whitworth Whiteknight authored
22 include/parrot/api.h
@@ -14,7 +14,6 @@
14 14 #include "parrot/config.h"
15 15 #include "parrot/core_types.h"
16 16
17   -
18 17 #define PARROT_API PARROT_EXPORT
19 18
20 19 /* having a modified version of PARROT_ASSERT which resolves as an integer
@@ -129,17 +128,32 @@ Parrot_Int Parrot_api_flag(
129 128 FUNC_MODIFIES(*interp_pmc);
130 129
131 130 PARROT_API
  131 +Parrot_Int Parrot_api_get_exception_backtrace(
  132 + ARGMOD(PMC * interp_pmc),
  133 + ARGMOD(PMC * exception),
  134 + ARGOUT(Parrot_String ** bt))
  135 + __attribute__nonnull__(1)
  136 + __attribute__nonnull__(2)
  137 + __attribute__nonnull__(3)
  138 + FUNC_MODIFIES(* interp_pmc)
  139 + FUNC_MODIFIES(* exception)
  140 + FUNC_MODIFIES(* bt);
  141 +
  142 +PARROT_API
132 143 Parrot_Int Parrot_api_get_result(
133 144 ARGMOD(PMC * interp_pmc),
134 145 ARGOUT(Parrot_Int *is_error),
  146 + ARGOUT(PMC ** exception),
135 147 ARGOUT(Parrot_Int *exit_code),
136 148 ARGOUT(Parrot_String * errmsg))
137 149 __attribute__nonnull__(1)
138 150 __attribute__nonnull__(2)
139 151 __attribute__nonnull__(3)
140 152 __attribute__nonnull__(4)
  153 + __attribute__nonnull__(5)
141 154 FUNC_MODIFIES(* interp_pmc)
142 155 FUNC_MODIFIES(*is_error)
  156 + FUNC_MODIFIES(* exception)
143 157 FUNC_MODIFIES(*exit_code)
144 158 FUNC_MODIFIES(* errmsg);
145 159
@@ -262,9 +276,15 @@ Parrot_Int Parrot_api_set_warnings(
262 276 , PARROT_ASSERT_ARG(outfile))
263 277 #define ASSERT_ARGS_Parrot_api_flag __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
264 278 PARROT_ASSERT_ARG(interp_pmc))
  279 +#define ASSERT_ARGS_Parrot_api_get_exception_backtrace \
  280 + __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  281 + PARROT_ASSERT_ARG(interp_pmc) \
  282 + , PARROT_ASSERT_ARG(exception) \
  283 + , PARROT_ASSERT_ARG(bt))
265 284 #define ASSERT_ARGS_Parrot_api_get_result __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
266 285 PARROT_ASSERT_ARG(interp_pmc) \
267 286 , PARROT_ASSERT_ARG(is_error) \
  287 + , PARROT_ASSERT_ARG(exception) \
268 288 , PARROT_ASSERT_ARG(exit_code) \
269 289 , PARROT_ASSERT_ARG(errmsg))
270 290 #define ASSERT_ARGS_Parrot_api_get_runtime_path __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
10 include/parrot/debugger.h
@@ -223,6 +223,12 @@ void PDB_script_file(PARROT_INTERP, ARGIN(const char *command))
223 223 __attribute__nonnull__(1)
224 224 __attribute__nonnull__(2);
225 225
  226 +STRING * Parrot_dbg_get_exception_backtrace(PARROT_INTERP,
  227 + ARGMOD(PMC * exception))
  228 + __attribute__nonnull__(1)
  229 + __attribute__nonnull__(2)
  230 + FUNC_MODIFIES(* exception);
  231 +
226 232 long PDB_add_label(PARROT_INTERP,
227 233 ARGMOD(PDB_file_t *file),
228 234 ARGIN(const opcode_t *cur_opcode),
@@ -385,6 +391,10 @@ void PDB_watchpoint(PARROT_INTERP, ARGIN(const char *command))
385 391 #define ASSERT_ARGS_PDB_script_file __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
386 392 PARROT_ASSERT_ARG(interp) \
387 393 , PARROT_ASSERT_ARG(command))
  394 +#define ASSERT_ARGS_Parrot_dbg_get_exception_backtrace \
  395 + __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  396 + PARROT_ASSERT_ARG(interp) \
  397 + , PARROT_ASSERT_ARG(exception))
388 398 #define ASSERT_ARGS_PDB_add_label __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
389 399 PARROT_ASSERT_ARG(interp) \
390 400 , PARROT_ASSERT_ARG(file) \
8 include/parrot/exit.h
@@ -32,6 +32,12 @@ void Parrot_x_exit(PARROT_INTERP, int status)
32 32 __attribute__nonnull__(1);
33 33
34 34 PARROT_EXPORT
  35 +PARROT_DOES_NOT_RETURN
  36 +PARROT_COLD
  37 +void Parrot_x_jump_out(PARROT_INTERP, int status)
  38 + __attribute__nonnull__(1);
  39 +
  40 +PARROT_EXPORT
35 41 void Parrot_x_on_exit(PARROT_INTERP,
36 42 ARGIN(exit_handler_f function),
37 43 ARGIN_NULLOK(void *arg))
@@ -40,6 +46,8 @@ void Parrot_x_on_exit(PARROT_INTERP,
40 46
41 47 #define ASSERT_ARGS_Parrot_x_exit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
42 48 PARROT_ASSERT_ARG(interp))
  49 +#define ASSERT_ARGS_Parrot_x_jump_out __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  50 + PARROT_ASSERT_ARG(interp))
43 51 #define ASSERT_ARGS_Parrot_x_on_exit __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
44 52 PARROT_ASSERT_ARG(interp) \
45 53 , PARROT_ASSERT_ARG(function))
15 include/parrot/global_setup.h
@@ -25,21 +25,16 @@ void Parrot_gbl_initialize_core_pmcs(PARROT_INTERP, int pass)
25 25 /* HEADERIZER BEGIN: src/global_setup.c */
26 26 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
27 27
28   -PARROT_EXPORT
29   -void Parrot_gbl_set_config_hash_internal(
30   - ARGIN(const unsigned char* parrot_config),
31   - unsigned int parrot_config_size)
32   - __attribute__nonnull__(1);
33   -
34 28 void init_world(PARROT_INTERP)
35 29 __attribute__nonnull__(1);
36 30
37 31 void Parrot_gbl_init_world_once(PARROT_INTERP)
38 32 __attribute__nonnull__(1);
39 33
40   -#define ASSERT_ARGS_Parrot_gbl_set_config_hash_internal \
41   - __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
42   - PARROT_ASSERT_ARG(parrot_config))
  34 +void Parrot_gbl_set_config_hash_internal(
  35 + ARGIN(const unsigned char* parrot_config),
  36 + unsigned int parrot_config_size)
  37 + __attribute__nonnull__(1);
43 38
44 39 void Parrot_set_config_hash_pmc(PARROT_INTERP, ARGMOD(PMC * config))
45 40 __attribute__nonnull__(1)
@@ -50,7 +45,7 @@ void Parrot_set_config_hash_pmc(PARROT_INTERP, ARGMOD(PMC * config))
50 45 PARROT_ASSERT_ARG(interp))
51 46 #define ASSERT_ARGS_Parrot_gbl_init_world_once __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
52 47 PARROT_ASSERT_ARG(interp))
53   -#define ASSERT_ARGS_Parrot_set_config_hash_internal \
  48 +#define ASSERT_ARGS_Parrot_gbl_set_config_hash_internal \
54 49 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
55 50 PARROT_ASSERT_ARG(parrot_config))
56 51 #define ASSERT_ARGS_Parrot_set_config_hash_pmc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
7 include/parrot/hll.h
@@ -52,7 +52,9 @@ PMC* Parrot_hll_get_HLL_namespace(PARROT_INTERP, int hll_id)
52 52 __attribute__nonnull__(1);
53 53
54 54 PARROT_EXPORT
55   -INTVAL Parrot_hll_get_HLL_type(PARROT_INTERP, INTVAL hll_id, INTVAL core_type)
  55 +INTVAL Parrot_hll_get_HLL_type(PARROT_INTERP,
  56 + INTVAL hll_id,
  57 + INTVAL core_type)
56 58 __attribute__nonnull__(1);
57 59
58 60 PARROT_EXPORT
@@ -74,7 +76,8 @@ void Parrot_hll_register_HLL_type(PARROT_INTERP,
74 76 void Parrot_hll_init_HLL(PARROT_INTERP)
75 77 __attribute__nonnull__(1);
76 78
77   -#define ASSERT_ARGS_Parrot_hll_get_ctx_HLL_namespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  79 +#define ASSERT_ARGS_Parrot_hll_get_ctx_HLL_namespace \
  80 + __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
78 81 PARROT_ASSERT_ARG(interp))
79 82 #define ASSERT_ARGS_Parrot_hll_get_ctx_HLL_type __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
80 83 PARROT_ASSERT_ARG(interp))
4 include/parrot/interpreter.h
@@ -267,8 +267,8 @@ struct parrot_interp_t {
267 267 * inside the invoke these get moved to the context structure */
268 268 PMC *current_cont; /* the return continuation PMC */
269 269 Parrot_jump_buff *api_jmp_buf; /* jmp point out of Parrot */
270   - STRING * final_error; /* string to hold the final error message */
271   - Parrot_Int exit_code;
  270 + PMC * final_exception; /* Final exception PMC */
  271 + INTVAL exit_code;
272 272 };
273 273
274 274 /* typedef struct parrot_interp_t Interp; done in parrot.h so that
77 src/debug.c
@@ -122,6 +122,15 @@ static void no_such_register(PARROT_INTERP,
122 122 UINTVAL register_num)
123 123 __attribute__nonnull__(1);
124 124
  125 +static STRING * PDB_get_continuation_backtrace(PARROT_INTERP,
  126 + ARGMOD(PMC * sub),
  127 + ARGMOD(PMC * ctx))
  128 + __attribute__nonnull__(1)
  129 + __attribute__nonnull__(2)
  130 + __attribute__nonnull__(3)
  131 + FUNC_MODIFIES(* sub)
  132 + FUNC_MODIFIES(* ctx);
  133 +
125 134 PARROT_WARN_UNUSED_RESULT
126 135 PARROT_CANNOT_RETURN_NULL
127 136 PARROT_PURE_FUNCTION
@@ -155,6 +164,11 @@ static const char * skip_whitespace(ARGIN(const char *cmd))
155 164 PARROT_ASSERT_ARG(pdb))
156 165 #define ASSERT_ARGS_no_such_register __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
157 166 PARROT_ASSERT_ARG(interp))
  167 +#define ASSERT_ARGS_PDB_get_continuation_backtrace \
  168 + __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  169 + PARROT_ASSERT_ARG(interp) \
  170 + , PARROT_ASSERT_ARG(sub) \
  171 + , PARROT_ASSERT_ARG(ctx))
158 172 #define ASSERT_ARGS_skip_whitespace __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
159 173 PARROT_ASSERT_ARG(cmd))
160 174 /* 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))
3242 3256 }
3243 3257 }
3244 3258
  3259 +STRING *
  3260 +Parrot_dbg_get_exception_backtrace(PARROT_INTERP, ARGMOD(PMC * exception))
  3261 +{
  3262 + ASSERT_ARGS(PDB_backtrace)
  3263 + STRING *str;
  3264 + PMC *old = PMCNULL;
  3265 + int rec_level = 0;
  3266 + int limit_count = 0;
  3267 +
  3268 + PMC * resume = VTABLE_get_attr_str(interp, exception, CONST_STRING(interp, "resume"));
  3269 + if (PMC_IS_NULL(resume))
  3270 + return STRINGNULL;
  3271 + else {
  3272 + const Parrot_Continuation_attributes * const cont = PARROT_CONTINUATION(resume);
  3273 + STRING * const bt = PDB_get_continuation_backtrace(interp, PMCNULL, cont->to_ctx);
  3274 + return bt;
  3275 + }
  3276 +}
  3277 +
3245 3278 /*
3246 3279
3247 3280 =item C<void PDB_backtrace(PARROT_INTERP)>
@@ -3257,19 +3290,27 @@ void
3257 3290 PDB_backtrace(PARROT_INTERP)
3258 3291 {
3259 3292 ASSERT_ARGS(PDB_backtrace)
3260   - STRING *str;
3261   - PMC *old = PMCNULL;
3262   - int rec_level = 0;
3263   - int limit_count = 0;
3264   -
3265 3293 /* information about the current sub */
3266 3294 PMC *sub = interpinfo_p(interp, CURRENT_SUB);
3267 3295 PMC *ctx = CURRENT_CONTEXT(interp);
  3296 + STRING * const bt = PDB_get_continuation_backtrace(interp, sub, ctx);
  3297 + Parrot_io_eprintf(interp, "%Ss", bt);
  3298 +}
  3299 +
  3300 +static STRING *
  3301 +PDB_get_continuation_backtrace(PARROT_INTERP, ARGMOD(PMC * sub), ARGMOD(PMC * ctx))
  3302 +{
  3303 + ASSERT_ARGS(PDB_get_continuation_backtrace)
  3304 + STRING *str;
  3305 + PMC *old = PMCNULL;
  3306 + PMC *output = Parrot_pmc_new(interp, enum_class_StringBuilder);
  3307 + int rec_level = 0;
  3308 + int limit_count = 0;
3268 3309
3269 3310 if (!PMC_IS_NULL(sub)) {
3270 3311 str = Parrot_Context_infostr(interp, ctx);
3271 3312 if (str) {
3272   - Parrot_io_eprintf(interp, "%Ss", str);
  3313 + VTABLE_push_string(interp, output, str);
3273 3314 if (interp->code->annotations) {
3274 3315 PMC *annot = PackFile_Annotations_lookup(interp, interp->code->annotations,
3275 3316 Parrot_pcc_get_pc(interp, ctx) - interp->code->base.data + 1, NULL);
@@ -3279,13 +3320,14 @@ PDB_backtrace(PARROT_INTERP)
3279 3320 PMC *pline = VTABLE_get_pmc_keyed_str(interp, annot,
3280 3321 Parrot_str_new_constant(interp, "line"));
3281 3322 if ((!PMC_IS_NULL(pfile)) && (!PMC_IS_NULL(pline))) {
3282   - STRING *file = VTABLE_get_string(interp, pfile);
  3323 + STRING * const file = VTABLE_get_string(interp, pfile);
3283 3324 INTVAL line = VTABLE_get_integer(interp, pline);
3284   - Parrot_io_eprintf(interp, " (%Ss:%li)", file, (long)line);
  3325 + STRING * const fmt = Parrot_sprintf_c(interp, " (%Ss:%li)", file, (long)line);
  3326 + VTABLE_push_string(interp, output, fmt);
3285 3327 }
3286 3328 }
3287 3329 }
3288   - Parrot_io_eprintf(interp, "\n");
  3330 + VTABLE_push_string(interp, output, CONST_STRING(interp, "\n"));
3289 3331 }
3290 3332 }
3291 3333
@@ -3328,7 +3370,8 @@ PDB_backtrace(PARROT_INTERP)
3328 3370 ++rec_level;
3329 3371 }
3330 3372 else if (rec_level != 0) {
3331   - Parrot_io_eprintf(interp, "... call repeated %d times\n", rec_level);
  3373 + STRING * const fmt = Parrot_sprintf_c(interp, "... call repeated %d times\n", rec_level);
  3374 + VTABLE_push_string(interp, output, fmt);
3332 3375 rec_level = 0;
3333 3376 }
3334 3377
@@ -3349,11 +3392,12 @@ PDB_backtrace(PARROT_INTERP)
3349 3392 if ((!PMC_IS_NULL(pfile)) && (!PMC_IS_NULL(pline))) {
3350 3393 STRING *file = VTABLE_get_string(interp, pfile);
3351 3394 INTVAL line = VTABLE_get_integer(interp, pline);
3352   - Parrot_io_eprintf(interp, " (%Ss:%li)", file, (long)line);
  3395 + STRING * const fmt = Parrot_sprintf_c(interp, " (%Ss:%li)", file, (long)line);
  3396 + VTABLE_push_string(interp, output, fmt);
3353 3397 }
3354 3398 }
3355 3399 }
3356   - Parrot_io_eprintf(interp, "\n");
  3400 + VTABLE_push_string(interp, output, CONST_STRING(interp, "\n"));
3357 3401 }
3358 3402
3359 3403 /* get the next Continuation */
@@ -3364,10 +3408,15 @@ PDB_backtrace(PARROT_INTERP)
3364 3408 break;
3365 3409 }
3366 3410
3367   - if (rec_level != 0)
3368   - Parrot_io_eprintf(interp, "... call repeated %d times\n", rec_level);
  3411 + if (rec_level != 0) {
  3412 + STRING * const fmt = Parrot_sprintf_c(interp, "... call repeated %d times\n", rec_level);
  3413 + VTABLE_push_string(interp, output, fmt);
  3414 + }
  3415 + return VTABLE_get_string(interp, output);
3369 3416 }
3370 3417
  3418 +
  3419 +
3371 3420 /*
3372 3421 * GDB functions
3373 3422 *
28 src/embed/api.c
@@ -9,15 +9,33 @@
9 9 PARROT_API
10 10 Parrot_Int
11 11 Parrot_api_get_result(ARGMOD(PMC * interp_pmc), ARGOUT(Parrot_Int *is_error),
  12 + ARGOUT(PMC ** exception),
12 13 ARGOUT(Parrot_Int *exit_code), ARGOUT(Parrot_String * errmsg))
13 14 {
14   - EMBED_API_CALLIN(interp_pmc, interp);
  15 + EMBED_API_CALLIN(interp_pmc, interp)
15 16 *exit_code = interp->exit_code;
16   - *errmsg = interp->final_error;
17   - *is_error = !interp->exit_code && *errmsg;
18   - interp->final_error = NULL;
  17 + *exception = interp->final_exception;
  18 + if (PMC_IS_NULL(exception)) {
  19 + *is_error = 0;
  20 + *errmsg = STRINGNULL;
  21 + } else {
  22 + *is_error = !interp->exit_code;
  23 + *errmsg = VTABLE_get_string(interp, *exception);
  24 + }
  25 + // TODO: GC mark interp->final_exception
  26 + interp->final_exception = PMCNULL;
19 27 interp->exit_code = 0;
20   - EMBED_API_CALLOUT(interp_pmc, interp);
  28 + EMBED_API_CALLOUT(interp_pmc, interp)
  29 +}
  30 +
  31 +PARROT_API
  32 +Parrot_Int
  33 +Parrot_api_get_exception_backtrace(ARGMOD(PMC * interp_pmc), ARGMOD(PMC * exception), ARGOUT(Parrot_String ** bt))
  34 +{
  35 + EMBED_API_CALLIN(interp_pmc, interp)
  36 + STRING * const bts = Parrot_dbg_get_exception_backtrace(interp, exception);
  37 + *bt = bts;
  38 + EMBED_API_CALLOUT(interp_pmc, interp)
21 39 }
22 40
23 41 PARROT_API
4 src/embed/strings.c
@@ -11,7 +11,9 @@ Parrot_api_string_export_ascii(Parrot_PMC interp_pmc, ARGIN(Parrot_String string
11 11 //ASSERT_ARGS(Parrot_api_string_export)
12 12 EMBED_API_CALLIN(interp_pmc, interp);
13 13 if(!STRING_IS_NULL(string))
14   - *strout = Parrot_str_to_cstring(interp, string);
  14 + *strout = Parrot_str_to_cstring(interp, string);
  15 + else
  16 + *strout = NULL;
15 17 EMBED_API_CALLOUT(interp_pmc, interp);
16 18 }
17 19
20 src/exceptions.c
@@ -99,22 +99,19 @@ die_from_exception(PARROT_INTERP, ARGIN(PMC *exception))
99 99
100 100 STRING * const message = already_dying ? STRINGNULL :
101 101 VTABLE_get_string(interp, exception);
102   - INTVAL exit_status = 1;
103 102 const INTVAL severity = already_dying ? EXCEPT_fatal :
104 103 VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "severity"));
105 104
106   - interp->final_error = message;
107   - if (already_dying) {
108   - //fflush(stderr);
109   - //fprintf(stderr, "\n***FATAL ERROR: Exception thrown while dying from previous unhandled Exception\n");
110   - Parrot_x_exit(interp, EXCEPT_fatal);
111   - }
  105 + if (already_dying)
  106 + Parrot_x_jump_out(interp, 1);
112 107 else {
113 108 /* In some cases we have a fatal exception before the IO system
114 109 * is completely initialized. Do some attempt to output the
115 110 * message to stderr, to help diagnosing. */
116 111 const int use_perr = !PMC_IS_NULL(Parrot_io_STDERR(interp));
117 112 already_dying = 1;
  113 + interp->final_exception = exception;
  114 + interp->exit_code = 1;
118 115
119 116 /* flush interpreter output to get things printed in order */
120 117 if (!PMC_IS_NULL(Parrot_io_STDOUT(interp)))
@@ -146,7 +143,7 @@ die_from_exception(PARROT_INTERP, ARGIN(PMC *exception))
146 143 }
147 144 else if (severity == EXCEPT_exit) {
148 145 /* TODO: get exit status based on type */
149   - exit_status = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "exit_code"));
  146 + interp->exit_code = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "exit_code"));
150 147 }
151 148 else {
152 149 Parrot_io_eprintf(interp, "No exception handler and no message\n");
@@ -168,12 +165,7 @@ die_from_exception(PARROT_INTERP, ARGIN(PMC *exception))
168 165 if (interp->thread_data && interp->thread_data->tid)
169 166 pt_thread_detach(interp->thread_data->tid);
170 167
171   - /*
172   - * only main should run the destroy functions - exit handler chain
173   - * is freed during Parrot_x_exit
174   - */
175   - interp->final_error = message;
176   - Parrot_x_exit(interp, exit_status);
  168 + Parrot_x_jump_out(interp, 1);
177 169 }
178 170
179 171 /*
21 src/exit.c
@@ -64,6 +64,20 @@ PARROT_EXPORT
64 64 PARROT_DOES_NOT_RETURN
65 65 PARROT_COLD
66 66 void
  67 +Parrot_x_jump_out(PARROT_INTERP, int status)
  68 +{
  69 + ASSERT_ARGS(Parrot_x_jump_out)
  70 +
  71 + if (interp->api_jmp_buf)
  72 + longjmp(*(interp->api_jmp_buf), 1);
  73 + else
  74 + exit(status);
  75 +}
  76 +
  77 +PARROT_EXPORT
  78 +PARROT_DOES_NOT_RETURN
  79 +PARROT_COLD
  80 +void
67 81 Parrot_x_exit(PARROT_INTERP, int status)
68 82 {
69 83 ASSERT_ARGS(Parrot_x_exit)
@@ -94,12 +108,7 @@ Parrot_x_exit(PARROT_INTERP, int status)
94 108 }
95 109
96 110 interp->exit_handler_list = NULL;
97   - interp->exit_code = status;
98   -
99   - if (interp->api_jmp_buf)
100   - longjmp(*(interp->api_jmp_buf), 1);
101   - else
102   - exit(status);
  111 + Parrot_x_jump_out(interp, status);
103 112 }
104 113
105 114 /*
3  src/gc/mark_sweep.c
@@ -222,6 +222,9 @@ Parrot_gc_trace_root(PARROT_INTERP,
222 222 /* Walk the iodata */
223 223 Parrot_IOData_mark(interp, interp->piodata);
224 224
  225 + if (!PMC_IS_NULL(interp->final_exception))
  226 + Parrot_gc_mark_PMC_alive(interp, interp->final_exception);
  227 +
225 228 if (trace == GC_TRACE_FULL)
226 229 trace_system_areas(interp, mem_pools);
227 230
10 src/global_setup.c
@@ -39,17 +39,17 @@ static PMC * parrot_config_hash_global = NULL;
39 39 /* HEADERIZER BEGIN: static */
40 40 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
41 41
42   -static void Parrot_gbl_setup_2(PARROT_INTERP)
  42 +static void Parrot_gbl_set_config_hash_interpreter(PARROT_INTERP)
43 43 __attribute__nonnull__(1);
44 44
45   -static void Parrot_gbl_set_config_hash_interpreter(PARROT_INTERP)
  45 +static void Parrot_gbl_setup_2(PARROT_INTERP)
46 46 __attribute__nonnull__(1);
47 47
48   -#define ASSERT_ARGS_Parrot_gbl_setup_2 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
49   - PARROT_ASSERT_ARG(interp))
50 48 #define ASSERT_ARGS_Parrot_gbl_set_config_hash_interpreter \
51 49 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
52 50 PARROT_ASSERT_ARG(interp))
  51 +#define ASSERT_ARGS_Parrot_gbl_setup_2 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
  52 + PARROT_ASSERT_ARG(interp))
53 53 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
54 54 /* HEADERIZER END: static */
55 55
@@ -70,7 +70,7 @@ void
70 70 Parrot_gbl_set_config_hash_internal(ARGIN(const unsigned char* parrot_config),
71 71 unsigned int parrot_config_size)
72 72 {
73   - ASSERT_ARGS(Parrot_set_config_hash_internal)
  73 + ASSERT_ARGS(Parrot_gbl_set_config_hash_internal)
74 74 if (parrot_config_stored != NULL) {
75 75 parrot_config_stored = parrot_config;
76 76 parrot_config_size_stored = parrot_config_size;
44 src/main.c
@@ -24,14 +24,11 @@ Start Parrot
24 24 #include "parrot/longopt.h"
25 25 #include "parrot/api.h"
26 26
27   -
28   -
29 27 /* HEADERIZER HFILE: none */
30 28
31 29 /* HEADERIZER BEGIN: static */
32 30 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
33 31
34   -static void show_last_error_and_exit(Parrot_PMC interp);
35 32 static void help(void);
36 33 static void help_debug(void);
37 34 PARROT_WARN_UNUSED_RESULT
@@ -72,11 +69,16 @@ static void parseflags_minimal(
72 69 __attribute__nonnull__(3)
73 70 FUNC_MODIFIES(* initargs);
74 71
  72 +static void print_parrot_string(
  73 + Parrot_PMC interp,
  74 + FILE *vector,
  75 + Parrot_String str);
  76 +
  77 +static void show_last_error_and_exit(Parrot_PMC interp);
75 78 static void usage(ARGMOD(FILE *fp))
76 79 __attribute__nonnull__(1)
77 80 FUNC_MODIFIES(*fp);
78 81
79   -#define ASSERT_ARGS_show_last_error_and_exit __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
80 82 #define ASSERT_ARGS_help __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
81 83 #define ASSERT_ARGS_help_debug __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
82 84 #define ASSERT_ARGS_is_all_digits __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -93,6 +95,8 @@ static void usage(ARGMOD(FILE *fp))
93 95 #define ASSERT_ARGS_parseflags_minimal __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
94 96 PARROT_ASSERT_ARG(initargs) \
95 97 , PARROT_ASSERT_ARG(argv))
  98 +#define ASSERT_ARGS_print_parrot_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
  99 +#define ASSERT_ARGS_show_last_error_and_exit __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
96 100 #define ASSERT_ARGS_usage __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
97 101 PARROT_ASSERT_ARG(fp))
98 102 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
@@ -163,23 +167,35 @@ main(int argc, const char *argv[])
163 167 static void
164 168 show_last_error_and_exit(Parrot_PMC interp)
165 169 {
166   - Parrot_String errmsg;
167   - Parrot_Int exit_code;
168   - Parrot_Int is_error;
169   - if (!Parrot_api_get_result(interp, &is_error, &exit_code, &errmsg)){
  170 + Parrot_String errmsg, backtrace;
  171 + Parrot_Int exit_code, is_error;
  172 + Parrot_PMC exception;
  173 +
  174 + if (!(Parrot_api_get_result(interp, &is_error, &exception, &exit_code, &errmsg) &&
  175 + Parrot_api_get_exception_backtrace(interp, exception, &backtrace))) {
170 176 fprintf(stderr, "PARROT VM: Cannot recover\n");
171 177 exit(EXIT_FAILURE);
172 178 }
173 179
174   - /* if (errmsg) { */
175   - /* char * errmsg_raw; */
176   - /* Parrot_api_string_export_ascii(interp, errmsg, &errmsg_raw); */
177   - /* fprintf(stderr, "PARROT VM: %s\n", errmsg_raw); */
178   - /* Parrot_api_string_free_exported_ascii(interp, errmsg_raw); */
179   - /* } */
  180 + print_parrot_string(interp, stderr, errmsg);
  181 + print_parrot_string(interp, stderr, backtrace);
  182 +
180 183 exit(exit_code);
181 184 }
182 185
  186 +static void
  187 +print_parrot_string(Parrot_PMC interp, FILE *vector, Parrot_String str)
  188 +{
  189 + char * msg_raw;
  190 + if (!str)
  191 + return;
  192 + Parrot_api_string_export_ascii(interp, str, &msg_raw);
  193 + if (msg_raw) {
  194 + fprintf(vector, "%s\n", msg_raw);
  195 + Parrot_api_string_free_exported_ascii(interp, msg_raw);
  196 + }
  197 +}
  198 +
183 199 /*
184 200
185 201 =item C<static int is_all_digits(const char *s)>
16 src/pbc_disassemble.c
@@ -151,10 +151,12 @@ main(int argc, const char *argv[])
151 151 static void
152 152 show_last_error_and_exit(Parrot_PMC interp)
153 153 {
154   - Parrot_String errmsg;
155   - Parrot_Int exit_code;
156   - Parrot_Int is_error;
157   - if (!Parrot_api_get_result(interp, &is_error, &exit_code, &errmsg)){
  154 + Parrot_String errmsg, backtrace;
  155 + Parrot_Int exit_code, is_error;
  156 + Parrot_PMC exception;
  157 +
  158 + if (!(Parrot_api_get_result(interp, &is_error, &exception, &exit_code, &errmsg) &&
  159 + Parrot_api_get_exception_backtrace(interp, exception, &backtrace))) {
158 160 fprintf(stderr, "PARROT VM: Cannot recover\n");
159 161 exit(EXIT_FAILURE);
160 162 }
@@ -162,7 +164,11 @@ show_last_error_and_exit(Parrot_PMC interp)
162 164 if (errmsg) {
163 165 char * errmsg_raw;
164 166 Parrot_api_string_export_ascii(interp, errmsg, &errmsg_raw);
165   - fprintf(stderr, "PARROT VM: %s\n", errmsg_raw);
  167 + fprintf(stderr, "%s\n", errmsg_raw);
  168 + Parrot_api_string_free_exported_ascii(interp, errmsg_raw);
  169 +
  170 + Parrot_api_string_export_ascii(interp, backtrace, &errmsg_raw);
  171 + fprintf(stderr, "%s\n", errmsg_raw);
166 172 Parrot_api_string_free_exported_ascii(interp, errmsg_raw);
167 173 }
168 174 exit(exit_code);
16 tools/dev/pbc_to_exe.pir
@@ -114,10 +114,12 @@ HEADER
114 114 static void
115 115 show_last_error_and_exit(Parrot_PMC interp)
116 116 {
117   - Parrot_String errmsg;
118   - Parrot_Int exit_code;
119   - Parrot_Int is_error;
120   - if (!Parrot_api_get_result(interp, &is_error, &exit_code, &errmsg)){
  117 + Parrot_String errmsg, backtrace;
  118 + Parrot_Int exit_code, is_error;
  119 + Parrot_PMC exception;
  120 +
  121 + if (!(Parrot_api_get_result(interp, &is_error, &exception, &exit_code, &errmsg) &&
  122 + Parrot_api_get_exception_backtrace(interp, exception, &backtrace))) {
121 123 fprintf(stderr, "PARROT VM: Cannot recover\n");
122 124 exit(EXIT_FAILURE);
123 125 }
@@ -125,7 +127,11 @@ HEADER
125 127 if (errmsg) {
126 128 char * errmsg_raw;
127 129 Parrot_api_string_export_ascii(interp, errmsg, &errmsg_raw);
128   - fprintf(stderr, "PARROT VM: %s\n", errmsg_raw);
  130 + fprintf(stderr, "%s\n", errmsg_raw);
  131 + Parrot_api_string_free_exported_ascii(interp, errmsg_raw);
  132 +
  133 + Parrot_api_string_export_ascii(interp, backtrace, &errmsg_raw);
  134 + fprintf(stderr, "%s\n", errmsg_raw);
129 135 Parrot_api_string_free_exported_ascii(interp, errmsg_raw);
130 136 }
131 137 exit(exit_code);

0 comments on commit 2483c68

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