changeset 433:45662241d9cd

suite_aggrs now handling struct by value return types, also still missing: nesting, unions, arrays note: this doesn't compile against this same checked in revision of dyncall, but only my working copy; a future checkin will catch up
author Tassilo Philipp
date Sat, 22 Jan 2022 16:07:57 +0100
parents 167faab0c0be
children 3d2c5d156d78
files test/suite_aggrs/cases.c test/suite_aggrs/design.txt test/suite_aggrs/main.c test/suite_aggrs/mk-cases.lua
diffstat 4 files changed, 156 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/test/suite_aggrs/cases.c	Fri Jan 21 15:42:29 2022 +0100
+++ b/test/suite_aggrs/cases.c	Sat Jan 22 16:07:57 2022 +0100
@@ -25,15 +25,15 @@
 #include "globals.h"
 
 #define ret_v(X) 
-#define ret_c(X) return(K_c[X]);
-#define ret_s(X) return(K_s[X]);
-#define ret_i(X) return(K_i[X]);
-#define ret_j(X) return(K_j[X]);
-#define ret_l(X) return(K_l[X]);
-#define ret_p(X) return(K_p[X]);
-#define ret_f(X) return(K_f[X]);
-#define ret_d(X) return(K_d[X]);
-#define ret_a(X) return(K_a[X]);
+#define ret_c(X)   return(K_c[X]);
+#define ret_s(X)   return(K_s[X]);
+#define ret_i(X)   return(K_i[X]);
+#define ret_j(X)   return(K_j[X]);
+#define ret_l(X)   return(K_l[X]);
+#define ret_p(X)   return(K_p[X]);
+#define ret_f(X)   return(K_f[X]);
+#define ret_d(X)   return(K_d[X]);
+#define ret_a(X,t) return(*(t*)K_a[X]);
 
 #define v void
 #define c char
--- a/test/suite_aggrs/design.txt	Fri Jan 21 15:42:29 2022 +0100
+++ b/test/suite_aggrs/design.txt	Sat Jan 22 16:07:57 2022 +0100
@@ -1,3 +1,21 @@
+v{ddd}
+vd{ddd}
+vdd{ddd}
+vddd{ddd}
+vdddd{ddd}
+vddddd{ddd}
+vdddddd{ddd}
+vddddddd{ddd}
+vdddddddd{ddd}
+v{dd}
+vd{dd}
+vdd{dd}
+vddd{dd}
+vdddd{dd}
+vddddd{dd}
+vdddddd{dd}
+vddddddd{dd}
+vdddddddd{dd}
 viiiii{ii}
 viiiii{ici}
 viiiii{il}
@@ -25,3 +43,48 @@
 f{iii}
 f{iiii}
 ss{ii}
+v{ddd}ijf
+vd{ddd}ijf
+vdd{ddd}ijf
+vddd{ddd}ijf
+vdddd{ddd}ijf
+vddddd{ddd}ijf
+vdddddd{ddd}ijf
+vddddddd{ddd}ijf
+vdddddddd{ddd}ijf
+v{dd}ijf
+vd{dd}ijf
+vdd{dd}ijf
+vddd{dd}ijf
+vdddd{dd}ijf
+vddddd{dd}ijf
+vdddddd{dd}ijf
+vddddddd{dd}ijf
+vdddddddd{dd}ijf
+viiiii{ii}ijf
+viiiii{ici}ijf
+viiiii{il}ijf
+vfiiiii{il}ijf
+viiiiif{il}ijf
+viiiiif{li}ijf
+viiiii{il}fijf
+viiiii{li}fijf
+viiffiii{ps}ijf
+viiiiiff{li}ijf
+viiiiiff{il}ijf
+viiiii{il}ffijf
+viiiii{li}ffijf
+iijf
+i{}ijf
+i{i}ijf
+i{ii}ijf
+i{iii}ijf
+i{iiii}ijf
+fijf
+f{}ijf
+f{i}ijf
+f{ii}ijf
+d{ii}ijf
+f{iii}ijf
+f{iiii}ijf
+ss{ii}ijf
--- a/test/suite_aggrs/main.c	Fri Jan 21 15:42:29 2022 +0100
+++ b/test/suite_aggrs/main.c	Sat Jan 22 16:07:57 2022 +0100
@@ -48,16 +48,37 @@
 {
   DCCallVM   * p = (DCCallVM*) G_callvm;
   char const * sig = signature;
+  char const * sig_args;
   char         rtype;
+  DCstruct *   rtype_st = NULL;
+  funptr       rtype_st_cmp = NULL;
   char         atype;
   int          pos = 0;
   int          s = 0;
 
   clear_V();
-  
-  rtype = *sig++;
+
   dcReset(p);
 
+  if(*sig == '{') {
+    int len;
+    int i = find_agg_idx(&len, sig);
+    if(i == -1) {
+      printf("unknown rtype sig at '%s' ;", sig);
+      return 0;
+    }
+    rtype = *sig;
+    sig += len;
+
+	rtype_st_cmp = G_agg_cmpfuncs[i];
+    rtype_st = ((DCstruct*(*)())G_agg_newdcstfuncs[i])();
+    dcBeginCallStruct(p, rtype_st, DC_FALSE);
+  }
+  else
+    rtype = *sig++;
+
+  sig_args = sig;
+
   while ( (atype = *sig) != '\0') {
     pos++;
     switch(atype) {
@@ -70,21 +91,21 @@
       case 'f': dcArgFloat   (p,K_f[pos]); break;
       case 'd': dcArgDouble  (p,K_d[pos]); break;
       case '{': {
-	    /* find struct sig */
-		int len;
-		int i = find_agg_idx(&len, sig);
+        /* find struct sig */
+        int len;
+        int i = find_agg_idx(&len, sig);
         if(i == -1) {
-		  printf("unknown sig at '%s' ;", sig);
-		  return 0;
-		}
-		DCstruct *st = ((DCstruct*(*)())G_agg_newdcstfuncs[i])();
-		dcArgStruct(p, st, K_a[pos]);
-		sig += len-1; /* advance to next arg char */
-		break;
+          printf("unknown sig at '%s' ;", sig);
+          return 0;
+        }
+        DCstruct *st = ((DCstruct*(*)())G_agg_newdcstfuncs[i])();
+        dcArgStruct(p, st, K_a[pos]);
+        sig += len-1; /* advance to next arg char */
+        break;
       }
       default: printf("unknown atype '%c' (1) ;", atype); return 0;
     }
-	++sig;
+    ++sig;
   }
   
   switch(rtype) 
@@ -98,40 +119,44 @@
     case 'p': s = (dcCallPointer (p,t) == K_p[pos]) ; break;
     case 'f': s = (dcCallFloat   (p,t) == K_f[pos]) ; break;
     case 'd': s = (dcCallDouble  (p,t) == K_d[pos]) ; break;
-    //@@@ handle return types case '{': @@@ ; break;
+    case '{': {
+      s = ((int(*)())rtype_st_cmp)(dcCallStruct(p,t,rtype_st, V_a[pos]), K_a[pos]);
+	  break;
+	}
     default: printf("unknown rtype '%c'", rtype); return 0;
   }
 
   if (!s) { printf("rval wrong;"); return 0; }
-  /* test: */
-  sig = signature+1;
+
+  /* test V_* array against values passed to func: */
+  sig = sig_args;
   pos = 1;
   while ( (atype = *sig) != '\0') {
     switch(atype) {
-      case 'c': s = ( V_c[pos] == K_c[pos] ); if (!s) printf("'c':%d: %d != %d ; ", pos, V_c[pos], K_c[pos]); break;
-      case 's': s = ( V_s[pos] == K_s[pos] ); if (!s) printf("'s':%d: %d != %d ; ", pos, V_s[pos], K_s[pos]); break;
-      case 'i': s = ( V_i[pos] == K_i[pos] ); if (!s) printf("'i':%d: %d != %d ; ", pos, V_i[pos], K_i[pos]); break;
-      case 'j': s = ( V_j[pos] == K_j[pos] ); if (!s) printf("'j':%d: %ld != %ld ; ", pos, V_j[pos], K_j[pos]); break;
+      case 'c': s = ( V_c[pos] == K_c[pos] ); if (!s) printf("'c':%d: %d != %d ; ",     pos, V_c[pos], K_c[pos]); break;
+      case 's': s = ( V_s[pos] == K_s[pos] ); if (!s) printf("'s':%d: %d != %d ; ",     pos, V_s[pos], K_s[pos]); break;
+      case 'i': s = ( V_i[pos] == K_i[pos] ); if (!s) printf("'i':%d: %d != %d ; ",     pos, V_i[pos], K_i[pos]); break;
+      case 'j': s = ( V_j[pos] == K_j[pos] ); if (!s) printf("'j':%d: %ld != %ld ; ",   pos, V_j[pos], K_j[pos]); break;
       case 'l': s = ( V_l[pos] == K_l[pos] ); if (!s) printf("'l':%d: %lld != %lld ; ", pos, V_l[pos], K_l[pos]); break;
-      case 'p': s = ( V_p[pos] == K_p[pos] ); if (!s) printf("'p':%d: %lld != %lld ; ", pos, (long long) V_p[pos], (long long) K_p[pos]); break;
-      case 'f': s = ( V_f[pos] == K_f[pos] ); if (!s) printf("'f':%d: %f != %f ; ", pos, V_f[pos], K_f[pos]); break;
-      case 'd': s = ( V_d[pos] == K_d[pos] ); if (!s) printf("'d':%d: %f != %f ; ", pos, V_d[pos], K_d[pos]); break;
+      case 'p': s = ( V_p[pos] == K_p[pos] ); if (!s) printf("'p':%d: %p != %p ; ",     pos, V_p[pos], K_p[pos]); break;
+      case 'f': s = ( V_f[pos] == K_f[pos] ); if (!s) printf("'f':%d: %f != %f ; ",     pos, V_f[pos], K_f[pos]); break;
+      case 'd': s = ( V_d[pos] == K_d[pos] ); if (!s) printf("'d':%d: %f != %f ; ",     pos, V_d[pos], K_d[pos]); break;
       case '{': {
-	    /* no check: guaranteed to exist, or invoke func would've exited when passing args, above */
-		int len;
-		int i = find_agg_idx(&len, sig);
-		s = ((int(*)())G_agg_cmpfuncs[i])(V_a[pos], K_a[pos]);
-		if (!s) printf("'{':%d:  %lld != %lld ; ", pos, (long long) V_a[pos], (long long) K_a[pos]);
-		sig += len-1; /* advance to next arg char */
-		break;
-	  }
+        /* no check: guaranteed to exist, or invoke func would've exited when passing args, above */
+        int len;
+        int i = find_agg_idx(&len, sig);
+        s = ((int(*)())G_agg_cmpfuncs[i])(V_a[pos], K_a[pos]);
+        if (!s) printf("'{':%d:  *%p != *%p ; ", pos, V_a[pos], K_a[pos]);
+        sig += len-1; /* advance to next arg char */
+        break;
+      }
       default: printf("unknown atype '%c' ; ", atype); return 0;
     }
     if (!s) {
       printf("arg mismatch at %d ; ", pos);
       return 0;
     }
-	++sig;
+    ++sig;
     ++pos;
   }
   return 1;
--- a/test/suite_aggrs/mk-cases.lua	Fri Jan 21 15:42:29 2022 +0100
+++ b/test/suite_aggrs/mk-cases.lua	Sat Jan 22 16:07:57 2022 +0100
@@ -9,14 +9,13 @@
 function trim(l) return l:gsub("^%s+",""):gsub("%s+$","") end
 function mkcase(id,sig)
   local sig = trim(sig)
-  -- @@@ return value hard-guessed by first char, doesn't hold anymore
-  local h = { "/* ",id,":",sig," */ ",sig:sub(1,1), " f", id,"(","" }
+  local h = { "/* ",id,":",sig," */ " }
   local t = { "" }
-  local pos = 1
+  local pos = 0
   local n_nest = 0
   local aggr
   local aggr_sig = ''
-  for i = 2, #sig do 
+  for i = 1, #sig do
     local name = "a"..pos
     local ch   = sig:sub(i,i)
 
@@ -51,20 +50,33 @@
     if n_nest == 0 then
       -- struct types (more than one char) need copying via a func
       if #ch > 1 then
-        h[#h+1] = 'struct '..ch.." "..name
+        h[#h+1] = 'struct '..ch
         t[#t+1] = 'f_cp'..ch..'(V_a['..pos.."],&"..name..");"
       else
-        h[#h+1] = ch.." "..name
+        h[#h+1] = ch
         t[#t+1] = "V_"..ch.."["..pos.."]="..name..";"
       end
-      h[#h+1] = ","
+
+      -- is return type or func arg?
+      if pos == 0 then
+        h[#h+1] = " f"..id.."("
+        h[#h+1] = ''
+        t[#t] = ''  -- clear; aggr return type handled explicitly
+      else
+        h[#h+1] = ' '..name
+        h[#h+1] = ","
+      end
 
       pos = pos + 1
     end
   end
   maxargs = max(maxargs, pos-1)
   h[#h] = "){"
-  t[#t+1] = "ret_"..sig:sub(1,1).."("..(pos-1)..")}\n"
+  if #h[6] == 1 then
+    t[#t+1] = "ret_"..h[6].."("..(pos-1)..")}\n"
+  else
+    t[#t+1] = "ret_a("..(pos-1)..","..h[6]..")}\n"
+  end
   return table.concat(h,"")..table.concat(t,"")
 end
 
@@ -141,13 +153,18 @@
     io.write(" dcCloseStruct(st); return st; };\n")
   end
 
+  -- make table.concat work
+  if #agg_names > 0 then
+    table.insert(agg_names, 1, '')
+  end
+
   io.write(cases)
   io.write(mkfuntab(lineno))
   io.write(mksigtab(sigtab))
   io.write('const char* G_agg_sigs[]  = {\n\t"'..table.concat(agg_sigs, '",\n\t"')..'"\n};\n')
   io.write('int G_agg_sizes[] = {\n\t'..table.concat(agg_sizes, ',\n\t')..'\n};\n')
-  io.write('funptr G_agg_newdcstfuncs[] = {\n\t(funptr)&f_newdcst'..table.concat(agg_names, ',\n\t(funptr)&f_newdcst')..'\n};\n')
-  io.write('funptr G_agg_cmpfuncs[] = {\n\t(funptr)&f_cmp'..table.concat(agg_names, ',\n\t(funptr)&f_cmp')..'\n};\n')
+  io.write('funptr G_agg_newdcstfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_newdcst'),2)..'\n};\n')
+  io.write('funptr G_agg_cmpfuncs[] = {'..string.sub(table.concat(agg_names, ',\n\t(funptr)&f_cmp'),2)..'\n};\n')
   io.write("int G_maxargs = "..maxargs..";\n")
 end