aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2019-10-20 21:00:17 +0200
committerAndrea Corallo2020-01-01 11:37:58 +0100
commit8d08a8a1070435e12b77517808df34a8093abc67 (patch)
treee0c36b436542fa8ba835817c7e387a7a2fae6178 /src
parent7ba9a4c895b61d5c12118a18cb337f621bea4442 (diff)
downloademacs-8d08a8a1070435e12b77517808df34a8093abc67.tar.gz
emacs-8d08a8a1070435e12b77517808df34a8093abc67.zip
add fetch-handler operator
Diffstat (limited to 'src')
-rw-r--r--src/comp.c106
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)
280static void 281static void
281declare_block (Lisp_Object block_name) 282declare_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
1152static void 1153static void
1153emit_limple_push_handler (gcc_jit_rvalue *handler, gcc_jit_rvalue *handler_type, 1154emit_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
1217static void 1184static 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. */