+ * This is a generic version of universal call that
+ * only works for specific argument patterns.
+ *
+ * It allows ports to work on the Hugs Prelude immeduately,
+ * even if univeral_call_c_<os/specific> is not ported.
+ * ------------------------------------------------------------------------*/
+
+void universal_call_c_x86_generic
+( int n_args,
+ void* args,
+ char* argstr,
+ void* fun )
+{
+ unsigned int *p = (unsigned int*) args;
+
+#define ARG(n) (p[n*2])
+#define CMP(str) ((n_args + 1 == strlen(str)) && \
+ (!strncmp(str,argstr,n_args + 1)))
+
+#define CALL(retType,callTypes,callVals) \
+ ((retType(*)callTypes)(fun))callVals
+
+ if (CMP("i")) {
+ int res = CALL(int,(void),());
+ ARG(0) = res;
+ } else if (CMP("ii")) {
+ int arg1 = (int) ARG(1);
+ int res = CALL(int,(int),(arg1));
+ ARG(0) = res;
+ } else if (CMP("iii")) {
+ int arg1 = (int) ARG(1);
+ int arg2 = (int) ARG(2);
+ int res = CALL(int,(int,int),(arg1,arg2));
+ ARG(0) = res;
+ } else {
+ /* Do not have the generic call for this argument list. */
+ int i;
+ printf("Can not call external function at address %d\n",(int)fun);
+ printf("Argument string = '");
+ for(i=0;i<n_args;i++) {
+ printf("%c",(char)argstr[i]);
+ }
+ printf("' [%d arg(s)]\n",n_args);
+ assert(0);
+ }
+#undef CMP
+}
+
+/* --------------------------------------------------------------------------