diff options
| author | Andrea Corallo | 2019-11-21 16:09:30 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:38:08 +0100 |
| commit | 71b363e2b3c709e64f8ef8ab7446cc3a19573eeb (patch) | |
| tree | 0967d036c2e057cc899fcc9079a2cab943f80786 /src/comp.c | |
| parent | 23874aee8825a6f670b6c2da9eca2d9cf643b3af (diff) | |
| download | emacs-71b363e2b3c709e64f8ef8ab7446cc3a19573eeb.tar.gz emacs-71b363e2b3c709e64f8ef8ab7446cc3a19573eeb.zip | |
error handling rework
Diffstat (limited to 'src/comp.c')
| -rw-r--r-- | src/comp.c | 100 |
1 files changed, 60 insertions, 40 deletions
diff --git a/src/comp.c b/src/comp.c index f7950bcc72c..61f297ea3d0 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -70,14 +70,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 70 | #endif | 70 | #endif |
| 71 | #define SETJMP_NAME STR (SETJMP) | 71 | #define SETJMP_NAME STR (SETJMP) |
| 72 | 72 | ||
| 73 | /* Raise an internal compiler error if test. | ||
| 74 | msg is evaluated only in that case. */ | ||
| 75 | #define ICE_IF(test, msg) \ | ||
| 76 | do { \ | ||
| 77 | if (test) \ | ||
| 78 | ice (msg); \ | ||
| 79 | } while (0) | ||
| 80 | |||
| 81 | /* C side of the compiler context. */ | 73 | /* C side of the compiler context. */ |
| 82 | 74 | ||
| 83 | typedef struct { | 75 | typedef struct { |
| @@ -211,15 +203,6 @@ format_string (const char *format, ...) | |||
| 211 | } | 203 | } |
| 212 | 204 | ||
| 213 | static void | 205 | static void |
| 214 | ice (const char* msg) | ||
| 215 | { | ||
| 216 | if (msg) | ||
| 217 | xsignal1 (Qinternal_native_compiler_error, build_string (msg)); | ||
| 218 | else | ||
| 219 | xsignal0 (Qinternal_native_compiler_error); | ||
| 220 | } | ||
| 221 | |||
| 222 | static void | ||
| 223 | bcall0 (Lisp_Object f) | 206 | bcall0 (Lisp_Object f) |
| 224 | { | 207 | { |
| 225 | Ffuncall (1, &f); | 208 | Ffuncall (1, &f); |
| @@ -273,7 +256,7 @@ type_to_cast_field (gcc_jit_type *type) | |||
| 273 | else if (type == comp.lisp_obj_ptr_type) | 256 | else if (type == comp.lisp_obj_ptr_type) |
| 274 | field = comp.cast_union_as_lisp_obj_ptr; | 257 | field = comp.cast_union_as_lisp_obj_ptr; |
| 275 | else | 258 | else |
| 276 | ice ("unsupported cast"); | 259 | xsignal1 (Qnative_ice, build_string ("unsupported cast")); |
| 277 | 260 | ||
| 278 | return field; | 261 | return field; |
| 279 | } | 262 | } |
| @@ -282,7 +265,9 @@ static gcc_jit_block * | |||
| 282 | retrive_block (Lisp_Object block_name) | 265 | retrive_block (Lisp_Object block_name) |
| 283 | { | 266 | { |
| 284 | Lisp_Object value = Fgethash (block_name, comp.func_blocks_h, Qnil); | 267 | Lisp_Object value = Fgethash (block_name, comp.func_blocks_h, Qnil); |
| 285 | ICE_IF (NILP (value), "missing basic block"); | 268 | |
| 269 | if (NILP (value)) | ||
| 270 | xsignal1 (Qnative_ice, build_string ("missing basic block")); | ||
| 286 | 271 | ||
| 287 | return (gcc_jit_block *) xmint_pointer (value); | 272 | return (gcc_jit_block *) xmint_pointer (value); |
| 288 | } | 273 | } |
| @@ -293,8 +278,10 @@ declare_block (Lisp_Object block_name) | |||
| 293 | char *name_str = SSDATA (SYMBOL_NAME (block_name)); | 278 | char *name_str = SSDATA (SYMBOL_NAME (block_name)); |
| 294 | gcc_jit_block *block = gcc_jit_function_new_block (comp.func, name_str); | 279 | gcc_jit_block *block = gcc_jit_function_new_block (comp.func, name_str); |
| 295 | Lisp_Object value = make_mint_ptr (block); | 280 | Lisp_Object value = make_mint_ptr (block); |
| 296 | ICE_IF (!NILP (Fgethash (block_name, comp.func_blocks_h, Qnil)), | 281 | |
| 297 | "double basic block declaration"); | 282 | if (!NILP (Fgethash (block_name, comp.func_blocks_h, Qnil))) |
| 283 | xsignal1 (Qnative_ice, build_string ("double basic block declaration")); | ||
| 284 | |||
| 298 | Fputhash (block_name, value, comp.func_blocks_h); | 285 | Fputhash (block_name, value, comp.func_blocks_h); |
| 299 | } | 286 | } |
| 300 | 287 | ||
| @@ -343,8 +330,10 @@ declare_imported_func (Lisp_Object subr_sym, gcc_jit_type *ret_type, | |||
| 343 | int nargs, gcc_jit_type **types) | 330 | int nargs, gcc_jit_type **types) |
| 344 | { | 331 | { |
| 345 | /* Don't want to declare the same function two times. */ | 332 | /* Don't want to declare the same function two times. */ |
| 346 | ICE_IF (!NILP (Fgethash (subr_sym, comp.imported_funcs_h, Qnil)), | 333 | if (!NILP (Fgethash (subr_sym, comp.imported_funcs_h, Qnil))) |
| 347 | "unexpected double function declaration"); | 334 | xsignal2 (Qnative_ice, |
| 335 | build_string ("unexpected double function declaration"), | ||
| 336 | subr_sym); | ||
| 348 | 337 | ||
| 349 | if (nargs == MANY) | 338 | if (nargs == MANY) |
| 350 | { | 339 | { |
| @@ -396,7 +385,10 @@ emit_call (Lisp_Object subr_sym, gcc_jit_type *ret_type, ptrdiff_t nargs, | |||
| 396 | Lisp_Object func = | 385 | Lisp_Object func = |
| 397 | Fgethash (subr_sym, direct ? comp.exported_funcs_h: comp.imported_funcs_h, | 386 | Fgethash (subr_sym, direct ? comp.exported_funcs_h: comp.imported_funcs_h, |
| 398 | Qnil); | 387 | Qnil); |
| 399 | ICE_IF (NILP (func), "missing function declaration"); | 388 | if (NILP (func)) |
| 389 | xsignal2 (Qnative_ice, | ||
| 390 | build_string ("missing function declaration"), | ||
| 391 | subr_sym); | ||
| 400 | 392 | ||
| 401 | if (direct) | 393 | if (direct) |
| 402 | { | 394 | { |
| @@ -414,7 +406,10 @@ emit_call (Lisp_Object subr_sym, gcc_jit_type *ret_type, ptrdiff_t nargs, | |||
| 414 | gcc_jit_lvalue_access_field (comp.func_relocs, | 406 | gcc_jit_lvalue_access_field (comp.func_relocs, |
| 415 | NULL, | 407 | NULL, |
| 416 | (gcc_jit_field *) xmint_pointer (func)); | 408 | (gcc_jit_field *) xmint_pointer (func)); |
| 417 | ICE_IF (!f_ptr, "undeclared function relocation"); | 409 | if (!f_ptr) |
| 410 | xsignal2 (Qnative_ice, | ||
| 411 | build_string ("missing function relocation"), | ||
| 412 | subr_sym); | ||
| 418 | emit_comment (format_string ("calling subr: %s", | 413 | emit_comment (format_string ("calling subr: %s", |
| 419 | SSDATA (SYMBOL_NAME (subr_sym)))); | 414 | SSDATA (SYMBOL_NAME (subr_sym)))); |
| 420 | return gcc_jit_context_new_call_through_ptr (comp.ctxt, | 415 | return gcc_jit_context_new_call_through_ptr (comp.ctxt, |
| @@ -1092,7 +1087,11 @@ emit_set_internal (Lisp_Object args) | |||
| 1092 | #s(comp-mvar 6 1 t 3 nil)) | 1087 | #s(comp-mvar 6 1 t 3 nil)) |
| 1093 | */ | 1088 | */ |
| 1094 | /* TODO: Inline the most common case. */ | 1089 | /* TODO: Inline the most common case. */ |
| 1095 | ICE_IF (list_length (args) != 3, "unexpected arg length for insns"); | 1090 | if (list_length (args) != 3) |
| 1091 | xsignal2 (Qnative_ice, | ||
| 1092 | build_string ("unexpected arg length for insns"), | ||
| 1093 | args); | ||
| 1094 | |||
| 1096 | args = XCDR (args); | 1095 | args = XCDR (args); |
| 1097 | int i = 0; | 1096 | int i = 0; |
| 1098 | gcc_jit_rvalue *gcc_args[4]; | 1097 | gcc_jit_rvalue *gcc_args[4]; |
| @@ -1272,7 +1271,7 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1272 | else if (EQ (handler_spec, Qcondition_case)) | 1271 | else if (EQ (handler_spec, Qcondition_case)) |
| 1273 | h_num = CONDITION_CASE; | 1272 | h_num = CONDITION_CASE; |
| 1274 | else | 1273 | else |
| 1275 | ice ("incoherent insn"); | 1274 | xsignal2 (Qnative_ice, build_string ("incoherent insn"), insn); |
| 1276 | gcc_jit_rvalue *handler_type = | 1275 | gcc_jit_rvalue *handler_type = |
| 1277 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | 1276 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, |
| 1278 | comp.int_type, | 1277 | comp.int_type, |
| @@ -1372,9 +1371,13 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1372 | else if (EQ (FIRST (arg1), Qdirect_callref)) | 1371 | else if (EQ (FIRST (arg1), Qdirect_callref)) |
| 1373 | res = emit_limple_call_ref (XCDR (arg1), true); | 1372 | res = emit_limple_call_ref (XCDR (arg1), true); |
| 1374 | else | 1373 | else |
| 1375 | ice ("LIMPLE inconsistent arg1 for op ="); | 1374 | xsignal2 (Qnative_ice, |
| 1375 | build_string ("LIMPLE inconsistent arg1 for insn"), | ||
| 1376 | insn); | ||
| 1376 | 1377 | ||
| 1377 | ICE_IF (!res, gcc_jit_context_get_first_error (comp.ctxt)); | 1378 | if (!res) |
| 1379 | xsignal1 (Qnative_ice, | ||
| 1380 | build_string (gcc_jit_context_get_first_error (comp.ctxt))); | ||
| 1378 | 1381 | ||
| 1379 | emit_frame_assignment (arg[0], res); | 1382 | emit_frame_assignment (arg[0], res); |
| 1380 | } | 1383 | } |
| @@ -1480,7 +1483,9 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1480 | } | 1483 | } |
| 1481 | else | 1484 | else |
| 1482 | { | 1485 | { |
| 1483 | ice ("LIMPLE op inconsistent"); | 1486 | xsignal2 (Qnative_ice, |
| 1487 | build_string ("LIMPLE op inconsistent"), | ||
| 1488 | op); | ||
| 1484 | } | 1489 | } |
| 1485 | } | 1490 | } |
| 1486 | 1491 | ||
| @@ -2860,7 +2865,10 @@ compile_function (Lisp_Object func) | |||
| 2860 | Lisp_Object block_name = HASH_KEY (ht, i); | 2865 | Lisp_Object block_name = HASH_KEY (ht, i); |
| 2861 | Lisp_Object block = HASH_VALUE (ht, i); | 2866 | Lisp_Object block = HASH_VALUE (ht, i); |
| 2862 | Lisp_Object insns = CALL1I (comp-block-insns, block); | 2867 | Lisp_Object insns = CALL1I (comp-block-insns, block); |
| 2863 | ICE_IF (NILP (block) || NILP (insns), "basic block is missing or empty"); | 2868 | if (NILP (block) || NILP (insns)) |
| 2869 | xsignal1 (Qnative_ice, | ||
| 2870 | build_string ("basic block is missing or empty")); | ||
| 2871 | |||
| 2864 | 2872 | ||
| 2865 | comp.block = retrive_block (block_name); | 2873 | comp.block = retrive_block (block_name); |
| 2866 | while (CONSP (insns)) | 2874 | while (CONSP (insns)) |
| @@ -2871,10 +2879,12 @@ compile_function (Lisp_Object func) | |||
| 2871 | } | 2879 | } |
| 2872 | } | 2880 | } |
| 2873 | const char *err = gcc_jit_context_get_first_error (comp.ctxt); | 2881 | const char *err = gcc_jit_context_get_first_error (comp.ctxt); |
| 2874 | ICE_IF (err, | 2882 | if (err) |
| 2875 | format_string ("failing to compile function %s with error: %s", | 2883 | xsignal3 (Qnative_ice, |
| 2876 | SSDATA (SYMBOL_NAME (CALL1I (comp-func-symbol-name, func))), | 2884 | build_string ("failing to compile function"), |
| 2877 | err)); | 2885 | CALL1I (comp-func-symbol-name, func), |
| 2886 | build_string (err)); | ||
| 2887 | |||
| 2878 | SAFE_FREE (); | 2888 | SAFE_FREE (); |
| 2879 | } | 2889 | } |
| 2880 | 2890 | ||
| @@ -2890,7 +2900,8 @@ DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt, | |||
| 2890 | { | 2900 | { |
| 2891 | if (comp.ctxt) | 2901 | if (comp.ctxt) |
| 2892 | { | 2902 | { |
| 2893 | ice ("compiler context already taken"); | 2903 | xsignal1 (Qnative_ice, |
| 2904 | build_string ("compiler context already taken")); | ||
| 2894 | return Qnil; | 2905 | return Qnil; |
| 2895 | } | 2906 | } |
| 2896 | 2907 | ||
| @@ -3396,12 +3407,21 @@ syms_of_comp (void) | |||
| 3396 | DEFSYM (Qadvice, "advice"); | 3407 | DEFSYM (Qadvice, "advice"); |
| 3397 | 3408 | ||
| 3398 | /* To be signaled. */ | 3409 | /* To be signaled. */ |
| 3399 | DEFSYM (Qinternal_native_compiler_error, "internal-native-compiler-error"); | 3410 | |
| 3400 | Fput (Qinternal_native_compiler_error, Qerror_conditions, | 3411 | /* By the compiler. */ |
| 3401 | pure_list (Qinternal_native_compiler_error, Qerror)); | 3412 | DEFSYM (Qnative_compiler_error, "native-compiler-error"); |
| 3402 | Fput (Qinternal_native_compiler_error, Qerror_message, | 3413 | Fput (Qnative_compiler_error, Qerror_conditions, |
| 3414 | pure_list (Qnative_compiler_error, Qerror)); | ||
| 3415 | Fput (Qnative_compiler_error, Qerror_message, | ||
| 3416 | build_pure_c_string ("Native compiler error")); | ||
| 3417 | |||
| 3418 | DEFSYM (Qnative_ice, "native-ice"); | ||
| 3419 | Fput (Qnative_ice, Qerror_conditions, | ||
| 3420 | pure_list (Qnative_ice, Qnative_compiler_error, Qerror)); | ||
| 3421 | Fput (Qnative_ice, Qerror_message, | ||
| 3403 | build_pure_c_string ("Internal native compiler error")); | 3422 | build_pure_c_string ("Internal native compiler error")); |
| 3404 | 3423 | ||
| 3424 | /* By the load machinery. */ | ||
| 3405 | DEFSYM (Qnative_lisp_load_failed, "native-lisp-load-failed"); | 3425 | DEFSYM (Qnative_lisp_load_failed, "native-lisp-load-failed"); |
| 3406 | Fput (Qnative_lisp_load_failed, Qerror_conditions, | 3426 | Fput (Qnative_lisp_load_failed, Qerror_conditions, |
| 3407 | pure_list (Qnative_lisp_load_failed, Qerror)); | 3427 | pure_list (Qnative_lisp_load_failed, Qerror)); |