diff options
| author | Andrea Corallo | 2019-10-20 21:00:17 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-01-01 11:37:58 +0100 |
| commit | 8d08a8a1070435e12b77517808df34a8093abc67 (patch) | |
| tree | e0c36b436542fa8ba835817c7e387a7a2fae6178 /src | |
| parent | 7ba9a4c895b61d5c12118a18cb337f621bea4442 (diff) | |
| download | emacs-8d08a8a1070435e12b77517808df34a8093abc67.tar.gz emacs-8d08a8a1070435e12b77517808df34a8093abc67.zip | |
add fetch-handler operator
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp.c | 106 |
1 files changed, 60 insertions, 46 deletions
diff --git a/src/comp.c b/src/comp.c index be966c2709a..6b3ca832d98 100644 --- a/src/comp.c +++ b/src/comp.c | |||
| @@ -171,6 +171,7 @@ typedef struct { | |||
| 171 | Lisp_Object func_blocks_h; /* blk_name -> gcc_block. */ | 171 | Lisp_Object func_blocks_h; /* blk_name -> gcc_block. */ |
| 172 | Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */ | 172 | Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */ |
| 173 | Lisp_Object imported_funcs_h; /* subr_name -> reloc_field. */ | 173 | Lisp_Object imported_funcs_h; /* subr_name -> reloc_field. */ |
| 174 | Lisp_Object buffer_handler_vec; /* All locals used to store non local exit values. */ | ||
| 174 | Lisp_Object emitter_dispatcher; | 175 | Lisp_Object emitter_dispatcher; |
| 175 | gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */ | 176 | gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */ |
| 176 | gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */ | 177 | gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */ |
| @@ -280,7 +281,7 @@ retrive_block (Lisp_Object block_name) | |||
| 280 | static void | 281 | static void |
| 281 | declare_block (Lisp_Object block_name) | 282 | declare_block (Lisp_Object block_name) |
| 282 | { | 283 | { |
| 283 | char *name_str = (char *) SDATA (SYMBOL_NAME (block_name)); | 284 | char *name_str = SSDATA (SYMBOL_NAME (block_name)); |
| 284 | gcc_jit_block *block = gcc_jit_function_new_block (comp.func, name_str); | 285 | gcc_jit_block *block = gcc_jit_function_new_block (comp.func, name_str); |
| 285 | Lisp_Object value = make_mint_ptr (block); | 286 | Lisp_Object value = make_mint_ptr (block); |
| 286 | ICE_IF (!NILP (Fgethash (block_name, comp.func_blocks_h, Qnil)), | 287 | ICE_IF (!NILP (Fgethash (block_name, comp.func_blocks_h, Qnil)), |
| @@ -1151,23 +1152,12 @@ emit_limple_call_ref (Lisp_Object insn, bool direct) | |||
| 1151 | 1152 | ||
| 1152 | static void | 1153 | static void |
| 1153 | emit_limple_push_handler (gcc_jit_rvalue *handler, gcc_jit_rvalue *handler_type, | 1154 | emit_limple_push_handler (gcc_jit_rvalue *handler, gcc_jit_rvalue *handler_type, |
| 1154 | gcc_jit_block *handler_bb, gcc_jit_block *guarded_bb, | 1155 | EMACS_UINT handler_buff_n, gcc_jit_block *handler_bb, |
| 1155 | Lisp_Object clobbered_mvar) | 1156 | gcc_jit_block *guarded_bb, Lisp_Object clobbered_mvar) |
| 1156 | { | 1157 | { |
| 1157 | /* | 1158 | /* struct handler *c = push_handler (POP, type); */ |
| 1158 | Ex: (push-handler #s(comp-mvar 1 8 nil nil nil nil) | ||
| 1159 | #s(comp-mvar 1 7 t done symbol nil) | ||
| 1160 | catcher bb_2 bb_1). | ||
| 1161 | */ | ||
| 1162 | |||
| 1163 | static unsigned pushhandler_n; /* FIXME move at ctxt or func level. */ | ||
| 1164 | |||
| 1165 | /* struct handler *c = push_handler (POP, type); */ | ||
| 1166 | gcc_jit_lvalue *c = | 1159 | gcc_jit_lvalue *c = |
| 1167 | gcc_jit_function_new_local (comp.func, | 1160 | xmint_pointer (AREF (comp.buffer_handler_vec, handler_buff_n)); |
| 1168 | NULL, | ||
| 1169 | comp.handler_ptr_type, | ||
| 1170 | format_string ("c_%u", pushhandler_n)); | ||
| 1171 | 1161 | ||
| 1172 | gcc_jit_rvalue *args[] = { handler, handler_type }; | 1162 | gcc_jit_rvalue *args[] = { handler, handler_type }; |
| 1173 | gcc_jit_block_add_assignment ( | 1163 | gcc_jit_block_add_assignment ( |
| @@ -1189,29 +1179,6 @@ emit_limple_push_handler (gcc_jit_rvalue *handler, gcc_jit_rvalue *handler_type, | |||
| 1189 | res = | 1179 | res = |
| 1190 | emit_call (intern_c_string (SETJMP_NAME), comp.int_type, 1, args, false); | 1180 | emit_call (intern_c_string (SETJMP_NAME), comp.int_type, 1, args, false); |
| 1191 | emit_cond_jump (res, handler_bb, guarded_bb); | 1181 | emit_cond_jump (res, handler_bb, guarded_bb); |
| 1192 | |||
| 1193 | /* This emit the handler part. */ | ||
| 1194 | |||
| 1195 | comp.block = handler_bb; | ||
| 1196 | gcc_jit_lvalue *m_handlerlist = | ||
| 1197 | gcc_jit_rvalue_dereference_field (comp.current_thread, | ||
| 1198 | NULL, | ||
| 1199 | comp.m_handlerlist); | ||
| 1200 | gcc_jit_block_add_assignment ( | ||
| 1201 | comp.block, | ||
| 1202 | NULL, | ||
| 1203 | m_handlerlist, | ||
| 1204 | gcc_jit_lvalue_as_rvalue( | ||
| 1205 | gcc_jit_rvalue_dereference_field (gcc_jit_lvalue_as_rvalue (c), | ||
| 1206 | NULL, | ||
| 1207 | comp.handler_next_field))); | ||
| 1208 | emit_frame_assignment ( | ||
| 1209 | clobbered_mvar, | ||
| 1210 | gcc_jit_lvalue_as_rvalue( | ||
| 1211 | gcc_jit_rvalue_dereference_field (gcc_jit_lvalue_as_rvalue (c), | ||
| 1212 | NULL, | ||
| 1213 | comp.handler_val_field))); | ||
| 1214 | ++pushhandler_n; | ||
| 1215 | } | 1182 | } |
| 1216 | 1183 | ||
| 1217 | static void | 1184 | static void |
| @@ -1222,6 +1189,16 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1222 | Lisp_Object arg0 UNINIT; | 1189 | Lisp_Object arg0 UNINIT; |
| 1223 | gcc_jit_rvalue *res; | 1190 | gcc_jit_rvalue *res; |
| 1224 | 1191 | ||
| 1192 | Lisp_Object arg[6]; | ||
| 1193 | Lisp_Object p = XCDR (insn); | ||
| 1194 | ptrdiff_t n_args = list_length (p); | ||
| 1195 | unsigned i = 0; | ||
| 1196 | FOR_EACH_TAIL (p) | ||
| 1197 | { | ||
| 1198 | eassert (i < n_args); | ||
| 1199 | arg[i++] = XCAR (p); | ||
| 1200 | } | ||
| 1201 | |||
| 1225 | if (CONSP (args)) | 1202 | if (CONSP (args)) |
| 1226 | arg0 = XCAR (args); | 1203 | arg0 = XCAR (args); |
| 1227 | 1204 | ||
| @@ -1269,9 +1246,11 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1269 | } | 1246 | } |
| 1270 | else if (EQ (op, Qpush_handler)) | 1247 | else if (EQ (op, Qpush_handler)) |
| 1271 | { | 1248 | { |
| 1272 | gcc_jit_rvalue *handler = emit_mvar_val (arg0); | 1249 | /* (push-handler condition-case #s(comp-mvar 0 3 t (arith-error) cons nil) 1 bb_2 bb_1) */ |
| 1250 | gcc_jit_rvalue *handler = emit_mvar_val (arg[1]); | ||
| 1273 | int h_num UNINIT; | 1251 | int h_num UNINIT; |
| 1274 | Lisp_Object handler_spec = THIRD (args); | 1252 | Lisp_Object handler_spec = arg[0]; |
| 1253 | EMACS_UINT handler_buff_n = XFIXNUM (arg[2]); | ||
| 1275 | if (EQ (handler_spec, Qcatcher)) | 1254 | if (EQ (handler_spec, Qcatcher)) |
| 1276 | h_num = CATCHER; | 1255 | h_num = CATCHER; |
| 1277 | else if (EQ (handler_spec, Qcondition_case)) | 1256 | else if (EQ (handler_spec, Qcondition_case)) |
| @@ -1282,10 +1261,10 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1282 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, | 1261 | gcc_jit_context_new_rvalue_from_int (comp.ctxt, |
| 1283 | comp.int_type, | 1262 | comp.int_type, |
| 1284 | h_num); | 1263 | h_num); |
| 1285 | gcc_jit_block *handler_bb = retrive_block (FORTH (args)); | 1264 | gcc_jit_block *handler_bb = retrive_block (arg[3]); |
| 1286 | gcc_jit_block *guarded_bb = retrive_block (FIFTH (args)); | 1265 | gcc_jit_block *guarded_bb = retrive_block (arg[4]); |
| 1287 | emit_limple_push_handler (handler, handler_type, handler_bb, guarded_bb, | 1266 | emit_limple_push_handler (handler, handler_type, handler_buff_n, |
| 1288 | arg0); | 1267 | handler_bb, guarded_bb, arg0); |
| 1289 | } | 1268 | } |
| 1290 | else if (EQ (op, Qpop_handler)) | 1269 | else if (EQ (op, Qpop_handler)) |
| 1291 | { | 1270 | { |
| @@ -1309,6 +1288,30 @@ emit_limple_insn (Lisp_Object insn) | |||
| 1309 | comp.handler_next_field))); | 1288 | comp.handler_next_field))); |
| 1310 | 1289 | ||
| 1311 | } | 1290 | } |
| 1291 | else if (EQ (op, Qfetch_handler)) | ||
| 1292 | { | ||
| 1293 | EMACS_UINT handler_buff_n = XFIXNUM (SECOND (args)); | ||
| 1294 | gcc_jit_lvalue *c = | ||
| 1295 | xmint_pointer (AREF (comp.buffer_handler_vec, handler_buff_n)); | ||
| 1296 | gcc_jit_lvalue *m_handlerlist = | ||
| 1297 | gcc_jit_rvalue_dereference_field (comp.current_thread, | ||
| 1298 | NULL, | ||
| 1299 | comp.m_handlerlist); | ||
| 1300 | gcc_jit_block_add_assignment ( | ||
| 1301 | comp.block, | ||
| 1302 | NULL, | ||
| 1303 | m_handlerlist, | ||
| 1304 | gcc_jit_lvalue_as_rvalue( | ||
| 1305 | gcc_jit_rvalue_dereference_field (gcc_jit_lvalue_as_rvalue (c), | ||
| 1306 | NULL, | ||
| 1307 | comp.handler_next_field))); | ||
| 1308 | emit_frame_assignment ( | ||
| 1309 | arg0, | ||
| 1310 | gcc_jit_lvalue_as_rvalue( | ||
| 1311 | gcc_jit_rvalue_dereference_field (gcc_jit_lvalue_as_rvalue (c), | ||
| 1312 | NULL, | ||
| 1313 | comp.handler_val_field))); | ||
| 1314 | } | ||
| 1312 | else if (EQ (op, Qcall)) | 1315 | else if (EQ (op, Qcall)) |
| 1313 | { | 1316 | { |
| 1314 | gcc_jit_block_add_eval (comp.block, NULL, | 1317 | gcc_jit_block_add_eval (comp.block, NULL, |
| @@ -2759,7 +2762,7 @@ compile_function (Lisp_Object func) | |||
| 2759 | frame_size), | 2762 | frame_size), |
| 2760 | "local"); | 2763 | "local"); |
| 2761 | comp.frame = SAFE_ALLOCA (frame_size * sizeof (*comp.frame)); | 2764 | comp.frame = SAFE_ALLOCA (frame_size * sizeof (*comp.frame)); |
| 2762 | for (unsigned i = 0; i < frame_size; ++i) | 2765 | for (EMACS_INT i = 0; i < frame_size; ++i) |
| 2763 | comp.frame[i] = | 2766 | comp.frame[i] = |
| 2764 | gcc_jit_context_new_array_access ( | 2767 | gcc_jit_context_new_array_access ( |
| 2765 | comp.ctxt, | 2768 | comp.ctxt, |
| @@ -2789,6 +2792,16 @@ compile_function (Lisp_Object func) | |||
| 2789 | format_string ("local%u", i)); | 2792 | format_string ("local%u", i)); |
| 2790 | } | 2793 | } |
| 2791 | 2794 | ||
| 2795 | EMACS_UINT non_local_handlers = XFIXNUM (FUNCALL1 (comp-func-handler-cnt, func)); | ||
| 2796 | comp.buffer_handler_vec = make_vector (non_local_handlers, Qnil); | ||
| 2797 | for (unsigned i = 0; i < non_local_handlers; ++i) | ||
| 2798 | ASET (comp.buffer_handler_vec, i, | ||
| 2799 | make_mint_ptr ( | ||
| 2800 | gcc_jit_function_new_local (comp.func, | ||
| 2801 | NULL, | ||
| 2802 | comp.handler_ptr_type, | ||
| 2803 | format_string ("handler_%u", i)))); | ||
| 2804 | |||
| 2792 | comp.func_blocks_h = CALLN (Fmake_hash_table); | 2805 | comp.func_blocks_h = CALLN (Fmake_hash_table); |
| 2793 | 2806 | ||
| 2794 | /* Pre declare all basic blocks to gcc. | 2807 | /* Pre declare all basic blocks to gcc. |
| @@ -3304,6 +3317,7 @@ syms_of_comp (void) | |||
| 3304 | /* Others. */ | 3317 | /* Others. */ |
| 3305 | DEFSYM (Qpush_handler, "push-handler"); | 3318 | DEFSYM (Qpush_handler, "push-handler"); |
| 3306 | DEFSYM (Qpop_handler, "pop-handler"); | 3319 | DEFSYM (Qpop_handler, "pop-handler"); |
| 3320 | DEFSYM (Qfetch_handler, "fetch-handler"); | ||
| 3307 | DEFSYM (Qcondition_case, "condition-case"); | 3321 | DEFSYM (Qcondition_case, "condition-case"); |
| 3308 | /* call operands. */ | 3322 | /* call operands. */ |
| 3309 | DEFSYM (Qcatcher, "catcher"); /* FIXME use these allover. */ | 3323 | DEFSYM (Qcatcher, "catcher"); /* FIXME use these allover. */ |