shithub: femtolisp

Download patch

ref: 16807df966dc78dc9f11355f1cf18c88dc7c1253
parent: 98726d68b76ebcb668a38fe21a2caa9e929e0525
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Nov 10 20:00:32 EST 2024

apply_cl: use computed goto when possible

--- a/flisp.c
+++ b/flisp.c
@@ -836,9 +836,6 @@
 		((uint8_t*)(a))[3] = ((uint32_t)(i)>>24)&0xff; \
 	}while(0)
 
-#define OP(x) case x:
-#define NEXT_OP break
-
 /*
   stack on entry: <func>  <nargs args...>
   caller's responsibility:
@@ -893,9 +890,113 @@
 	PUSH(0); // captured?
 	FL(curr_frame) = FL(sp);
 
+#ifdef COMPUTED_GOTO
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#define OP(x) op_##x:
+#define NEXT_OP goto *((uint8_t*)&&op_OP_LOADA0 + ops[op = *ip++])
+	static const int ops[] = {
+		[OP_LOADA0] = (uint8_t*)&&op_OP_LOADA0 - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADA1] = (uint8_t*)&&op_OP_LOADA1 - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADV] = (uint8_t*)&&op_OP_LOADV - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRF] = (uint8_t*)&&op_OP_BRF - (uint8_t*)&&op_OP_LOADA0,
+		[OP_POP] = (uint8_t*)&&op_OP_POP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_CALL] = (uint8_t*)&&op_OP_CALL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_TCALL] = (uint8_t*)&&op_OP_TCALL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADG] = (uint8_t*)&&op_OP_LOADG - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADA] = (uint8_t*)&&op_OP_LOADA - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADC] = (uint8_t*)&&op_OP_LOADC - (uint8_t*)&&op_OP_LOADA0,
+		[OP_RET] = (uint8_t*)&&op_OP_RET - (uint8_t*)&&op_OP_LOADA0,
+		[OP_DUP] = (uint8_t*)&&op_OP_DUP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_CAR] = (uint8_t*)&&op_OP_CAR - (uint8_t*)&&op_OP_LOADA0,
+		[OP_CDR] = (uint8_t*)&&op_OP_CDR - (uint8_t*)&&op_OP_LOADA0,
+		[OP_CLOSURE] = (uint8_t*)&&op_OP_CLOSURE - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SETA] = (uint8_t*)&&op_OP_SETA - (uint8_t*)&&op_OP_LOADA0,
+		[OP_JMP] = (uint8_t*)&&op_OP_JMP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADC00] = (uint8_t*)&&op_OP_LOADC00 - (uint8_t*)&&op_OP_LOADA0,
+		[OP_PAIRP] = (uint8_t*)&&op_OP_PAIRP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRNE] = (uint8_t*)&&op_OP_BRNE - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADT] = (uint8_t*)&&op_OP_LOADT - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOAD0] = (uint8_t*)&&op_OP_LOAD0 - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADC01] = (uint8_t*)&&op_OP_LOADC01 - (uint8_t*)&&op_OP_LOADA0,
+		[OP_AREF] = (uint8_t*)&&op_OP_AREF - (uint8_t*)&&op_OP_LOADA0,
+		[OP_ATOMP] = (uint8_t*)&&op_OP_ATOMP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRT] = (uint8_t*)&&op_OP_BRT - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRNN] = (uint8_t*)&&op_OP_BRNN - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOAD1] = (uint8_t*)&&op_OP_LOAD1 - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LT] = (uint8_t*)&&op_OP_LT - (uint8_t*)&&op_OP_LOADA0,
+		[OP_ADD2] = (uint8_t*)&&op_OP_ADD2 - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SETCDR] = (uint8_t*)&&op_OP_SETCDR - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADF] = (uint8_t*)&&op_OP_LOADF - (uint8_t*)&&op_OP_LOADA0,
+		[OP_CONS] = (uint8_t*)&&op_OP_CONS - (uint8_t*)&&op_OP_LOADA0,
+		[OP_EQ] = (uint8_t*)&&op_OP_EQ - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SYMBOLP] = (uint8_t*)&&op_OP_SYMBOLP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_NOT] = (uint8_t*)&&op_OP_NOT - (uint8_t*)&&op_OP_LOADA0,
+		[OP_CADR] = (uint8_t*)&&op_OP_CADR - (uint8_t*)&&op_OP_LOADA0,
+		[OP_NEG] = (uint8_t*)&&op_OP_NEG - (uint8_t*)&&op_OP_LOADA0,
+		[OP_NULLP] = (uint8_t*)&&op_OP_NULLP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BOOLEANP] = (uint8_t*)&&op_OP_BOOLEANP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_NUMBERP] = (uint8_t*)&&op_OP_NUMBERP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_FIXNUMP] = (uint8_t*)&&op_OP_FIXNUMP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BOUNDP] = (uint8_t*)&&op_OP_BOUNDP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BUILTINP] = (uint8_t*)&&op_OP_BUILTINP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_FUNCTIONP] = (uint8_t*)&&op_OP_FUNCTIONP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_VECTORP] = (uint8_t*)&&op_OP_VECTORP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_NOP] = (uint8_t*)&&op_OP_NOP - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SETCAR] = (uint8_t*)&&op_OP_SETCAR - (uint8_t*)&&op_OP_LOADA0,
+		[OP_JMPL] = (uint8_t*)&&op_OP_JMPL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRFL] = (uint8_t*)&&op_OP_BRFL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRTL] = (uint8_t*)&&op_OP_BRTL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_EQV] = (uint8_t*)&&op_OP_EQV - (uint8_t*)&&op_OP_LOADA0,
+		[OP_EQUAL] = (uint8_t*)&&op_OP_EQUAL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LIST] = (uint8_t*)&&op_OP_LIST - (uint8_t*)&&op_OP_LOADA0,
+		[OP_APPLY] = (uint8_t*)&&op_OP_APPLY - (uint8_t*)&&op_OP_LOADA0,
+		[OP_ADD] = (uint8_t*)&&op_OP_ADD - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SUB] = (uint8_t*)&&op_OP_SUB - (uint8_t*)&&op_OP_LOADA0,
+		[OP_MUL] = (uint8_t*)&&op_OP_MUL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_DIV] = (uint8_t*)&&op_OP_DIV - (uint8_t*)&&op_OP_LOADA0,
+		[OP_IDIV] = (uint8_t*)&&op_OP_IDIV - (uint8_t*)&&op_OP_LOADA0,
+		[OP_NUMEQ] = (uint8_t*)&&op_OP_NUMEQ - (uint8_t*)&&op_OP_LOADA0,
+		[OP_COMPARE] = (uint8_t*)&&op_OP_COMPARE - (uint8_t*)&&op_OP_LOADA0,
+		[OP_ARGC] = (uint8_t*)&&op_OP_ARGC - (uint8_t*)&&op_OP_LOADA0,
+		[OP_VECTOR] = (uint8_t*)&&op_OP_VECTOR - (uint8_t*)&&op_OP_LOADA0,
+		[OP_ASET] = (uint8_t*)&&op_OP_ASET - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADNIL] = (uint8_t*)&&op_OP_LOADNIL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADI8] = (uint8_t*)&&op_OP_LOADI8 - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADVL] = (uint8_t*)&&op_OP_LOADVL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADGL] = (uint8_t*)&&op_OP_LOADGL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADAL] = (uint8_t*)&&op_OP_LOADAL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LOADCL] = (uint8_t*)&&op_OP_LOADCL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SETG] = (uint8_t*)&&op_OP_SETG - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SETGL] = (uint8_t*)&&op_OP_SETGL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SETAL] = (uint8_t*)&&op_OP_SETAL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SETC] = (uint8_t*)&&op_OP_SETC - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SETCL] = (uint8_t*)&&op_OP_SETCL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_VARGC] = (uint8_t*)&&op_OP_VARGC - (uint8_t*)&&op_OP_LOADA0,
+		[OP_TRYCATCH] = (uint8_t*)&&op_OP_TRYCATCH - (uint8_t*)&&op_OP_LOADA0,
+		[OP_FOR] = (uint8_t*)&&op_OP_FOR - (uint8_t*)&&op_OP_LOADA0,
+		[OP_TAPPLY] = (uint8_t*)&&op_OP_TAPPLY - (uint8_t*)&&op_OP_LOADA0,
+		[OP_SUB2] = (uint8_t*)&&op_OP_SUB2 - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LARGC] = (uint8_t*)&&op_OP_LARGC - (uint8_t*)&&op_OP_LOADA0,
+		[OP_LVARGC] = (uint8_t*)&&op_OP_LVARGC - (uint8_t*)&&op_OP_LOADA0,
+		[OP_CALLL] = (uint8_t*)&&op_OP_CALLL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_TCALLL] = (uint8_t*)&&op_OP_TCALLL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRNEL] = (uint8_t*)&&op_OP_BRNEL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRNNL] = (uint8_t*)&&op_OP_BRNNL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRN] = (uint8_t*)&&op_OP_BRN - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRNL] = (uint8_t*)&&op_OP_BRNL - (uint8_t*)&&op_OP_LOADA0,
+		[OP_OPTARGS] = (uint8_t*)&&op_OP_OPTARGS - (uint8_t*)&&op_OP_LOADA0,
+		[OP_BRBOUND] = (uint8_t*)&&op_OP_BRBOUND - (uint8_t*)&&op_OP_LOADA0,
+		[OP_KEYARGS] = (uint8_t*)&&op_OP_KEYARGS - (uint8_t*)&&op_OP_LOADA0,
+	};
+	NEXT_OP;
+#else
+#define OP(x) case x:
+#define NEXT_OP break
 	op = *ip++;
 	while(1){
 		switch(op){
+#endif
 		OP(OP_LOADA0)
 			PUSH(captured ? vector_elt(FL(stack)[bp], 0) : FL(stack)[bp]);
 			NEXT_OP;
@@ -970,7 +1071,11 @@
 						case OP_DIV:	goto apply_div;
 						default:
 							op = i;
+#ifdef COMPUTED_GOTO
+							goto *((uint8_t*)&&op_OP_LOADA0 + ops[i]);
+#else
 							continue;
+#endif
 						}
 					}
 				}
@@ -1742,9 +1847,17 @@
 			FL(stack)[ipd] = (uintptr_t)ip;
 			nargs = process_keys(v, i, n, labs(s)-(i+n), bp, nargs, s<0);
 			NEXT_OP;
+
+		OP(OP_NOP)
+			NEXT_OP;
+
+#ifdef COMPUTED_GOTO
+#pragma GCC diagnostic pop
+#else
 		}
 		op = *ip++;
 	}
+#endif
 }
 
 #define SWAP_INT32(a)
--- a/posix/platform.h
+++ b/posix/platform.h
@@ -25,6 +25,8 @@
 #include <wctype.h>
 #include <wchar.h>
 
+#define COMPUTED_GOTO
+
 #define LLT_ALLOC(n) malloc(n)
 #define LLT_REALLOC(p, n) realloc((p), (n))
 #define LLT_FREE(x) free(x)