changeset 84:67961454902b

- bigger cleanup in callvm code * changed init of most callvms to reuse code and for consistency * removed unused functions * general changes for consistency * added some missing cconv defines do mode calls - fixed potential buffer overrun on arm64 - fixed sparc and x64 mode setting (only one mode, but wasn't (pointlessly) resettable) - error code handling (dcGetError) changes, flag is now cleared (work still underway) - Changelog update
author cslag
date Wed, 06 Apr 2016 00:21:51 +0200
parents 54930a037e8a
children 8439d9e57d08
files ChangeLog ToDo dyncall/dyncall_api.c dyncall/dyncall_callvm_arm32_arm.c dyncall/dyncall_callvm_arm32_arm.h dyncall/dyncall_callvm_arm32_arm_armhf.c dyncall/dyncall_callvm_arm32_arm_armhf.h dyncall/dyncall_callvm_arm32_thumb.c dyncall/dyncall_callvm_arm32_thumb.h dyncall/dyncall_callvm_arm64.c dyncall/dyncall_callvm_arm64.h dyncall/dyncall_callvm_arm64_apple.c dyncall/dyncall_callvm_mips_eabi.c dyncall/dyncall_callvm_mips_eabi.h dyncall/dyncall_callvm_mips_n32.c dyncall/dyncall_callvm_mips_n64.c dyncall/dyncall_callvm_mips_n64.h dyncall/dyncall_callvm_mips_o32.c dyncall/dyncall_callvm_mips_o32.h dyncall/dyncall_callvm_ppc32.c dyncall/dyncall_callvm_ppc32.h dyncall/dyncall_callvm_ppc64.c dyncall/dyncall_callvm_ppc64.h dyncall/dyncall_callvm_sparc.c dyncall/dyncall_callvm_sparc.h dyncall/dyncall_callvm_sparc64.c dyncall/dyncall_callvm_sparc64.h dyncall/dyncall_callvm_sparc_v9.c dyncall/dyncall_callvm_sparc_v9.h dyncall/dyncall_callvm_x64.c dyncall/dyncall_callvm_x64.h dyncall/dyncall_callvm_x86.c dyncall/dyncall_callvm_x86.h
diffstat 33 files changed, 408 insertions(+), 537 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Mar 28 23:46:59 2016 +0200
+++ b/ChangeLog	Wed Apr 06 00:21:51 2016 +0200
@@ -4,12 +4,17 @@
 dyncall:
   o better C++ compiler support (for pointer conversions)
   o PPC64 single-precision float fixes for more than 13 float args (thanks Masanori!)
+  o fixed potential buffer overrun on arm64
+  o error code handling (dcGetError) changes, flag is now cleared (work still
+    underway)
 dyncallback:
   o PPC64 single-precision float fixes for more than 13 float args (thanks Masanori!)
 doc:
   o working html doc generation from TEX sources
 bindings:
-  o python: updated to latest signature format (was still on 0.1), cleanup
+  o better documentation, removed relative path dependencies, general cleanup
+  o python: updated to latest signature format (was still on 0.1)
+  o java: rewritten (old version was never complete, anyways)
 
 Version 0.9 (2015/12/31)
 dyncall:
--- a/ToDo	Mon Mar 28 23:46:59 2016 +0200
+++ b/ToDo	Wed Apr 06 00:21:51 2016 +0200
@@ -1,5 +1,11 @@
 1.0:
 ----
+- !!! the CallVM-free functions are per VTable, however the latter can be changed out
+      at runtime... which basically changes potentially the deallocator...
+      same goes for functions setting the mode. think about how to make this safer - currently
+      we have a higher flexibility and we need to potentially clean up from the mode we are in,
+      however, this is open to misuse
+- !!! dcGetError flags get set, but not unset after successful calls
 - check all vararg calling conv implementations if they promote correctly
   (e.g. float to double); we used to not care as it was the user's job to
   think of that, but we allow users to use ArgFloat, etc. on "..." now,
@@ -55,6 +61,7 @@
 - get rid of Dl_info and friends (_GNU_SOURCE) in dynload/dynload_syms_elf.c
   for implementation of dlSymsNameFromValue(..)
 - check if PSP can support dynload (missing elf.h, dlfcn.h, etc.); fixup readme if successful
+- some functionality like java's System.mapLibraryName('name') might be helpful?
 
 dyncallback:
 ------------
@@ -67,12 +74,10 @@
 - release bindings as standalone packages (already done for rbdc as a gem and rdyncall on cran)
   * add note to documentation, where bindings are and that some bindings are svn-only ATM
 - add rdoc documentation to ruby gem
-- bring python up to latest
 - add pydoc for python
 - add manpage for shdc
 - expose callf-convenience functions to go
 - add godoc for godc
-- bring java up to latest
 - add javadoc to java
 - add more bindings
 - add callback support for erlang, go, java, lua, python and ruby (and shell? how?)
--- a/dyncall/dyncall_api.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_api.c	Wed Apr 06 00:21:51 2016 +0200
@@ -157,12 +157,13 @@
   return vm->mError;
 }
 
-const char* dcGetErrorString(int mode)
-{
-  switch(mode) {
-    case DC_ERROR_NONE: return "none";
-    case DC_ERROR_UNSUPPORTED_MODE: return "unsupported mode";
-    default: return "(unknown mode id)";
-  }
-}
+//@@@ not used, (re)introduce or cleanup
+//const char* dcGetErrorString(int mode)
+//{
+//  switch(mode) {
+//    case DC_ERROR_NONE: return "none";
+//    case DC_ERROR_UNSUPPORTED_MODE: return "unsupported mode";
+//    default: return "(unknown mode id)";
+//  }
+//}
 
--- a/dyncall/dyncall_callvm_arm32_arm.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_arm32_arm.c	Wed Apr 06 00:21:51 2016 +0200
@@ -41,18 +41,6 @@
 #include "dyncall_callvm_arm32_arm.h"
 #include "dyncall_alloc.h"
 
-static void dc_callvm_mode_arm32_arm(DCCallVM* in_self,DCint mode);
-
-static DCCallVM* dc_callvm_new_arm32_arm(DCCallVM_vt* vt, DCsize size)
-{
-  /* Store at least 16 bytes (4 words) for internal spill area. Assembly code depends on it. */
-  DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)dcAllocMem(sizeof(DCCallVM_arm32_arm)+size+16);
-  dc_callvm_base_init(&self->mInterface, vt);
-  dcVecInit(&self->mVecHead, size);
-  return (DCCallVM*)self;
-}
-
-
 static void dc_callvm_free_arm32_arm(DCCallVM* in_self)
 {
   dcFreeMem(in_self);
@@ -152,6 +140,7 @@
   dcCall_arm32_arm(target, dcVecData(&self->mVecHead), dcVecSize(&self->mVecHead));
 }
 
+static void dc_callvm_mode_arm32_arm(DCCallVM* in_self, DCint mode);
 
 DCCallVM_vt gVT_arm32_arm =
 {
@@ -181,7 +170,6 @@
 , NULL /* callStruct */
 };
 
-
 DCCallVM_vt gVT_arm32_arm_eabi =
 {
   &dc_callvm_free_arm32_arm
@@ -210,42 +198,39 @@
 , NULL /* callStruct */
 };
 
+static void dc_callvm_mode_arm32_arm(DCCallVM* in_self, DCint mode)
+{
+  DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*)in_self;
+  DCCallVM_vt* vt;
 
-DCCallVM* dcNewCallVM_arm32_arm(DCsize size) 
-{
+  switch(mode) {
+    case DC_CALL_C_ELLIPSIS:
+    case DC_CALL_C_ELLIPSIS_VARARGS:
 /* Check OS if we need EABI as default. */
 #if defined(DC__ABI_ARM_EABI)
-  return dc_callvm_new_arm32_arm(&gVT_arm32_arm_eabi, size);
+    case DC_CALL_C_DEFAULT:       vt = &gVT_arm32_arm_eabi; break;
 #else
-  return dc_callvm_new_arm32_arm(&gVT_arm32_arm, size);
+    case DC_CALL_C_DEFAULT:       vt = &gVT_arm32_arm;      break;
 #endif
-}
-
-
-DCCallVM* dcNewCallVM(DCsize size)
-{
-  return dcNewCallVM_arm32_arm(size);
+    case DC_CALL_C_ARM_ARM:       vt = &gVT_arm32_arm;      break;
+    case DC_CALL_C_ARM_ARM_EABI:  vt = &gVT_arm32_arm_eabi; break;
+    default: 
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return;
+  }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
-static void dc_callvm_mode_arm32_arm(DCCallVM* in_self,DCint mode)
+/* Public API. */
+DCCallVM* dcNewCallVM(DCsize size)
 {
-  DCCallVM_arm32_arm* self = (DCCallVM_arm32_arm*) in_self;
-  DCCallVM_vt*  vt;
-  switch(mode) {
-/* Check OS if we need EABI as default. */
-    case DC_CALL_C_ELLIPSIS:
-    case DC_CALL_C_ELLIPSIS_VARARGS:
-#if defined(DC__ABI_ARM_EABI)
-    case DC_CALL_C_DEFAULT:          vt = &gVT_arm32_arm_eabi; break;
-#else
-    case DC_CALL_C_DEFAULT:          vt = &gVT_arm32_arm;      break;
-#endif
-    case DC_CALL_C_ARM_ARM:          vt = &gVT_arm32_arm;      break;
-    case DC_CALL_C_ARM_ARM_EABI:     vt = &gVT_arm32_arm_eabi; break;
-    default: 
-      in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
-      return;
-  }
-  self->mInterface.mVTpointer = vt;
+  /* Store at least 16 bytes (4 words) for internal spill area. Assembly code depends on it. */
+  DCCallVM_arm32_arm* p = (DCCallVM_arm32_arm*)dcAllocMem(sizeof(DCCallVM_arm32_arm)+size+16);
+
+  dc_callvm_mode_arm32_arm((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_arm32_arm.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_arm32_arm.h	Wed Apr 06 00:21:51 2016 +0200
@@ -45,7 +45,6 @@
 #include "dyncall_callvm.h"
 #include "dyncall_vector.h"
 
-
 typedef struct
 {
   DCCallVM  mInterface;
@@ -53,8 +52,5 @@
   DCVecHead mVecHead;
 } DCCallVM_arm32_arm;
 
-DCCallVM* dcNewCallVM_arm32_arm(DCsize size);
-
-
 #endif /* DYNCALL_CALLVM_ARM32_ARM_H */
 
--- a/dyncall/dyncall_callvm_arm32_arm_armhf.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_arm32_arm_armhf.c	Wed Apr 06 00:21:51 2016 +0200
@@ -28,20 +28,6 @@
 #include "dyncall_alloc.h"
 
 
-static DCCallVM* dc_callvm_new_arm32_armhf(DCCallVM_vt* vt, DCsize size)
-{
-  /* Store at least 16 bytes (4 words for first 4 int args) for internal spill area. Assembly code depends on it. */
-  DCCallVM_arm32_armhf* p = (DCCallVM_arm32_armhf*)dcAllocMem(sizeof(DCCallVM_arm32_armhf)+size+16);
-  dc_callvm_base_init(&p->mInterface, vt);
-  dcVecInit(&p->mVecHead, size);
-  p->i = 0;
-  p->s = 0;
-  p->d = 0;
-  return (DCCallVM*)p;
-}
-
-static void mode(DCCallVM* in_self,DCint mode);
-
 static void deinit(DCCallVM* in_self)
 {
   dcFreeMem(in_self);
@@ -145,6 +131,8 @@
   dcCall_arm32_armhf(target, dcVecData(&p->mVecHead), dcVecSize(&p->mVecHead), &p->S[0]);
 }
 
+static void mode(DCCallVM* in_self,DCint mode);
+
 DCCallVM_vt vt_armhf =
 {
   &deinit
@@ -201,34 +189,38 @@
 , NULL /* callStruct */
 };
 
-DCCallVM* dcNewCallVM(DCsize size)
+static void mode(DCCallVM* in_self, DCint mode)
 {
-#if defined(DC__ABI_ARM_EABI)
-  return dc_callvm_new_arm32_arm(&eabi, size);
-#elif defined(DC__ABI_ARM_HF)
-  return dc_callvm_new_arm32_armhf(&vt_armhf, size);
-#elif defined(DC__ABI_ARM_OABI)
-  return dc_callvm_new_arm32_arm(&oabi, size);
-#else
-#error unknown ARM abi
-#endif
-}
+  DCCallVM_arm32_armhf* self = (DCCallVM_arm32_armhf*)in_self;
+  DCCallVM_vt* vt;
 
-static void mode(DCCallVM* in_self,DCint mode)
-{
-  DCCallVM_arm32_armhf* self = (DCCallVM_arm32_armhf*) in_self;
   switch(mode) {
     case DC_CALL_C_DEFAULT:
     case DC_CALL_C_ARM_ARMHF:
-      self->mInterface.mVTpointer = &vt_armhf;
+      vt = &vt_armhf;
       break;
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
-      self->mInterface.mVTpointer = &vt_armhf_ellipsis;
+      vt = &vt_armhf_ellipsis;
       break;
     default:
-      in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
       return;
   }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
+/* Public API. */
+DCCallVM* dcNewCallVM(DCsize size)
+{
+  /* Store at least 16 bytes (4 words for first 4 int args) for internal spill area. Assembly code depends on it. */
+  DCCallVM_arm32_armhf* p = (DCCallVM_arm32_armhf*)dcAllocMem(sizeof(DCCallVM_arm32_armhf)+size+16);
+
+  mode((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  reset((DCCallVM*)p);
+
+  return (DCCallVM*)p;
+}
+
--- a/dyncall/dyncall_callvm_arm32_arm_armhf.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_arm32_arm_armhf.h	Wed Apr 06 00:21:51 2016 +0200
@@ -45,7 +45,6 @@
 #include "dyncall_callvm.h"
 #include "dyncall_vector.h"
 
-
 typedef struct
 {
   DCCallVM     mInterface;
@@ -57,8 +56,5 @@
   DCVecHead    mVecHead;
 } DCCallVM_arm32_armhf;
 
-DCCallVM* dcNewCallVM_arm32_armhf(DCsize size);
-
-
 #endif /* DYNCALL_CALLVM_ARM32_ARM_H */
 
--- a/dyncall/dyncall_callvm_arm32_thumb.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_arm32_thumb.c	Wed Apr 06 00:21:51 2016 +0200
@@ -43,16 +43,6 @@
 
 static void dc_callvm_mode_arm32_thumb(DCCallVM* in_self,DCint mode);
 
-static DCCallVM* dc_callvm_new_arm32_thumb(DCCallVM_vt* vt, DCsize size)
-{
-  /* Store at least 16 bytes (4 words) for internal spill area. Assembly code depends on it. */
-  DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)dcAllocMem(sizeof(DCCallVM_arm32_thumb)+size+16);
-  dc_callvm_base_init(&self->mInterface, vt);
-  dcVecInit(&self->mVecHead, size);
-  return (DCCallVM*)self;
-}
-
-
 static void dc_callvm_free_arm32_thumb(DCCallVM* in_self)
 {
   dcFreeMem(in_self);
@@ -181,7 +171,6 @@
 , NULL /* callStruct */
 };
 
-
 DCCallVM_vt gVT_arm32_thumb_eabi =
 {
   &dc_callvm_free_arm32_thumb
@@ -210,40 +199,39 @@
 , NULL /* callStruct */
 };
 
+static void dc_callvm_mode_arm32_thumb(DCCallVM* in_self, DCint mode)
+{
+  DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*)in_self;
+  DCCallVM_vt* vt;
 
-DCCallVM* dcNewCallVM_arm32_thumb(DCsize size) 
-{
+  switch(mode) {
+    case DC_CALL_C_ELLIPSIS:
+    case DC_CALL_C_ELLIPSIS_VARARGS:
 /* Check OS if we need EABI as default. */
 #if defined(DC__ABI_ARM_EABI)
-  return dc_callvm_new_arm32_thumb(&gVT_arm32_thumb_eabi, size);
+    case DC_CALL_C_DEFAULT:        vt = &gVT_arm32_thumb_eabi; break;
 #else
-  return dc_callvm_new_arm32_thumb(&gVT_arm32_thumb, size);
+    case DC_CALL_C_DEFAULT:        vt = &gVT_arm32_thumb;      break;
 #endif
-}
-
-
-DCCallVM* dcNewCallVM(DCsize size)
-{
-  return dcNewCallVM_arm32_thumb(size);
+    case DC_CALL_C_ARM_THUMB:      vt = &gVT_arm32_thumb;      break;
+    case DC_CALL_C_ARM_THUMB_EABI: vt = &gVT_arm32_thumb_eabi; break;
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return;
+  }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
-
-static void dc_callvm_mode_arm32_thumb(DCCallVM* in_self,DCint mode)
+/* Public API. */
+DCCallVM* dcNewCallVM(DCsize size)
 {
-  DCCallVM_arm32_thumb* self = (DCCallVM_arm32_thumb*) in_self;
-  DCCallVM_vt*  vt;
-  switch(mode) {
-/* Check OS if we need EABI as default. */
-    case DC_CALL_C_ELLIPSIS:
-#if defined(DC__ABI_ARM_EABI)
-    case DC_CALL_C_DEFAULT:          vt = &gVT_arm32_thumb_eabi; break;
-#else
-    case DC_CALL_C_DEFAULT:          vt = &gVT_arm32_thumb;      break;
-#endif
-    case DC_CALL_C_ARM_THUMB:        vt = &gVT_arm32_thumb;      break;
-    case DC_CALL_C_ARM_THUMB_EABI:   vt = &gVT_arm32_thumb_eabi; break;
-    default: self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return;
-  }
-  self->mInterface.mVTpointer = vt;
+  /* Store at least 16 bytes (4 words) for internal spill area. Assembly code depends on it. */
+  DCCallVM_arm32_thumb* p = (DCCallVM_arm32_thumb*)dcAllocMem(sizeof(DCCallVM_arm32_thumb)+size+16);
+
+  dc_callvm_mode_arm32_thumb((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_arm32_thumb.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_arm32_thumb.h	Wed Apr 06 00:21:51 2016 +0200
@@ -45,7 +45,6 @@
 #include "dyncall_callvm.h"
 #include "dyncall_vector.h"
 
-
 typedef struct
 {
   DCCallVM  mInterface;
@@ -53,8 +52,5 @@
   DCVecHead mVecHead;
 } DCCallVM_arm32_thumb;
 
-DCCallVM* dcNewCallVM_arm32_thumb(DCsize size);
-
-
 #endif /* DYNCALL_CALLVM_ARM32_THUMB_H */
 
--- a/dyncall/dyncall_callvm_arm64.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_arm64.c	Wed Apr 06 00:21:51 2016 +0200
@@ -27,19 +27,6 @@
 #include "dyncall_callvm_arm64.h"
 #include "dyncall_alloc.h"
 
-static DCCallVM* dc_callvm_new_arm64(DCCallVM_vt* vt, DCsize size)
-{
-  DCCallVM_arm64* p = (DCCallVM_arm64*) dcAllocMem(size);
-
-  dc_callvm_base_init(&p->mInterface, vt);
-
-  dcVecInit(&p->mVecHead, size);
-
-  p->i = 0;
-  p->f = 0;
-
-  return (DCCallVM*)p;
-}
 
 static void reset(DCCallVM* in_p)
 {
@@ -50,8 +37,6 @@
 }
 
 
-static void mode(DCCallVM* in_self,DCint mode);
-
 static void deinit(DCCallVM* in_self)
 {
   dcFreeMem(in_self);
@@ -112,6 +97,8 @@
   dcCall_arm64(target, dcVecData(&p->mVecHead), ( dcVecSize(&p->mVecHead) + 15 ) & -16, &p->u.S[0]);
 }
 
+static void mode(DCCallVM* in_self, DCint mode);
+
 DCCallVM_vt vt_arm64 =
 {
   &deinit
@@ -140,26 +127,35 @@
 , NULL /* callStruct */
 };
 
-DCCallVM* dcNewCallVM(DCsize size) 
+static void mode(DCCallVM* in_self, DCint mode)
 {
-  return dc_callvm_new_arm64(&vt_arm64, size);
-}
+  DCCallVM_arm64* self = (DCCallVM_arm64*)in_self;
+  DCCallVM_vt* vt;
 
-static void mode(DCCallVM* in_self,DCint mode)
-{
-  DCCallVM_arm64* self = (DCCallVM_arm64*) in_self;
-  DCCallVM_vt*  vt;
   switch(mode) {
     case DC_CALL_C_DEFAULT:        
+    case DC_CALL_C_ARM64:        
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
-    case DC_CALL_C_ARM64:        
       vt = &vt_arm64;
       break;
     default: 
-      in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
       return;
   }
-  self->mInterface.mVTpointer = vt;
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
+/* Public API. */
+DCCallVM* dcNewCallVM(DCsize size) 
+{
+  DCCallVM_arm64* p = (DCCallVM_arm64*)dcAllocMem(sizeof(DCCallVM_arm64)+size);
+
+  mode((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  reset((DCCallVM*)p);
+
+  return (DCCallVM*)p;
+}
+
--- a/dyncall/dyncall_callvm_arm64.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_arm64.h	Wed Apr 06 00:21:51 2016 +0200
@@ -30,7 +30,6 @@
 #include "dyncall_callvm.h"
 #include "dyncall_vector.h"
 
-
 typedef struct
 {
   DCCallVM mInterface;
@@ -44,8 +43,5 @@
   DCVecHead mVecHead;	/* argument buffer head */
 } DCCallVM_arm64;
 
-DCCallVM* dcNewCallVM_arm64(DCsize size);
-
-
 #endif /* DYNCALL_CALLVM_ARM64_DEBIAN_H */
 
--- a/dyncall/dyncall_callvm_arm64_apple.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_arm64_apple.c	Wed Apr 06 00:21:51 2016 +0200
@@ -27,19 +27,6 @@
 #include "dyncall_callvm_arm64.h"
 #include "dyncall_alloc.h"
 
-static DCCallVM* dc_callvm_new_arm64(DCCallVM_vt* vt, DCsize size)
-{
-  DCCallVM_arm64* p = (DCCallVM_arm64*) dcAllocMem(size);
-
-  dc_callvm_base_init(&p->mInterface, vt);
-
-  dcVecInit(&p->mVecHead, size);
-
-  p->i = 0;
-  p->f = 0;
-
-  return (DCCallVM*)p;
-}
 
 static void reset(DCCallVM* in_p)
 {
@@ -50,8 +37,6 @@
 }
 
 
-static void mode(DCCallVM* in_p,DCint mode);
-
 static void deinit(DCCallVM* in_p)
 {
   dcFreeMem(in_p);
@@ -186,6 +171,8 @@
   dcCall_arm64(target, dcVecData(&p->mVecHead), ( dcVecSize(&p->mVecHead) + 15 ) & -16, &p->u.S[0]);
 }
 
+static void mode(DCCallVM* in_p,DCint mode);
+
 DCCallVM_vt vt_arm64 =
 {
   &deinit
@@ -242,21 +229,14 @@
 , NULL /* callStruct */
 };
 
-
-DCCallVM* dcNewCallVM(DCsize size) 
+static void mode(DCCallVM* in_self, DCint mode)
 {
-  return dc_callvm_new_arm64(&vt_arm64, size);
-}
+  DCCallVM_arm64* self = (DCCallVM_arm64*)in_self;
+  DCCallVM_vt* vt;
 
-static void mode(DCCallVM* in_self,DCint mode)
-{
-  DCCallVM_arm64* self = (DCCallVM_arm64*) in_self;
-  DCCallVM_vt*  vt;
   switch(mode) {
     case DC_CALL_C_DEFAULT:        
-    case DC_CALL_C_ARM64:        
-      vt = &vt_arm64;
-      break;
+    case DC_CALL_C_ARM64:
     case DC_CALL_C_ELLIPSIS:
       vt = &vt_arm64;
       break;
@@ -264,9 +244,22 @@
       vt = &vt_arm64_variadic;
       break;
     default: 
-      in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
       return;
   }
-  self->mInterface.mVTpointer = vt;
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
+/* Public API. */
+DCCallVM* dcNewCallVM(DCsize size) 
+{
+  DCCallVM_arm64* p = (DCCallVM_arm64*)dcAllocMem(sizeof(DCCallVM_arm64)+size);
+
+  mode((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  reset((DCCallVM*)p);
+
+  return (DCCallVM*)p;
+}
+
--- a/dyncall/dyncall_callvm_mips_eabi.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_mips_eabi.c	Wed Apr 06 00:21:51 2016 +0200
@@ -36,34 +36,11 @@
   self->mSingleRegs = 0;
 }
 
-static DCCallVM* dc_callvm_new_mips_eabi(DCCallVM_vt* vt, DCsize size)
-{
-  /* Store at least 16 bytes (4 words) for internal spill area. Assembly code depends on it. */
-  DCCallVM_mips_eabi* self = (DCCallVM_mips_eabi*)dcAllocMem(sizeof(DCCallVM_mips_eabi)+size+16);
-  dc_callvm_base_init(&self->mInterface, vt);
-  dcVecInit(&self->mVecHead, size);
-  dc_callvm_reset_mips_eabi( (DCCallVM*) self );
-  return (DCCallVM*)self;
-}
-
-
 static void dc_callvm_free_mips_eabi(DCCallVM* in_self)
 {
   dcFreeMem(in_self);
 }
 
-static void dc_callvm_mode_mips_eabi(DCCallVM* in_self,DCint mode)
-{
-  switch(mode) {
-    case DC_CALL_C_DEFAULT:
-    case DC_CALL_C_ELLIPSIS:
-    case DC_CALL_C_MIPS32_EABI:
-      break;
-    default:
-      in_self->mError = DC_ERROR_UNSUPPORTED_MODE; return;
-  }
-}
-
 /* arg int -- fillup integer register file OR push on stack */
 
 static void dc_callvm_argInt_mips_eabi(DCCallVM* in_self, DCint i)
@@ -142,6 +119,8 @@
   dcCall_mips_eabi(target, &self->mRegData, dcVecSize(&self->mVecHead), dcVecData(&self->mVecHead));
 }
 
+static void dc_callvm_mode_mips_eabi(DCCallVM* in_self, DCint mode);
+
 DCCallVM_vt gVT_mips_eabi =
 {
   &dc_callvm_free_mips_eabi
@@ -170,13 +149,37 @@
 , NULL /* callStruct */
 };
 
-DCCallVM* dcNewCallVM_mips_eabi(DCsize size) 
+/* mode: only a single mode available currently. */
+static void dc_callvm_mode_mips_eabi(DCCallVM* in_self, DCint mode)
 {
-  return dc_callvm_new_mips_eabi(&gVT_mips_eabi, size);
+  DCCallVM_mips_eabi* self = (DCCallVM_mips_eabi*)in_self;
+  DCCallVM_vt* vt;
+
+  switch(mode) {
+    case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_MIPS32_EABI:
+    case DC_CALL_C_ELLIPSIS:
+    case DC_CALL_C_ELLIPSIS_VARARGS:
+      vt = &gVT_mips_eabi;
+      break;
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return;
+  }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
+/* Public API. */
 DCCallVM* dcNewCallVM(DCsize size)
 {
-  return dcNewCallVM_mips_eabi(size);
+  /* Store at least 16 bytes (4 words) for internal spill area. Assembly code depends on it. */
+  DCCallVM_mips_eabi* p = (DCCallVM_mips_eabi*)dcAllocMem(sizeof(DCCallVM_mips_eabi)+size+16);
+
+  dc_callvm_mode_mips_eabi((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  dc_callvm_reset_mips_eabi((DCCallVM*)p);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_mips_eabi.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_mips_eabi.h	Wed Apr 06 00:21:51 2016 +0200
@@ -45,7 +45,6 @@
 #include "dyncall_callvm.h"
 #include "dyncall_vector.h"
 
-
 typedef struct
 {
   DCCallVM  mInterface;
@@ -55,8 +54,5 @@
   DCVecHead mVecHead;
 } DCCallVM_mips_eabi;
 
-DCCallVM* dcNewCallVM_mips_eabi(DCsize size);
-
-
 #endif /* DYNCALL_CALLVM_MIPS_EABI_H */
 
--- a/dyncall/dyncall_callvm_mips_n32.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_mips_n32.c	Wed Apr 06 00:21:51 2016 +0200
@@ -61,15 +61,6 @@
   self->mRegData.mUseDouble = 0LL;
 }
 
-static DCCallVM* dc_callvm_new_mips_n32(DCCallVM_vt* vt, DCsize size)
-{
-  DCCallVM_mips_n32* self = (DCCallVM_mips_n32*)dcAllocMem(sizeof(DCCallVM_mips_n32)+size);
-  dc_callvm_base_init(&self->mInterface, vt);
-  dcVecInit(&self->mVecHead, size);
-  dc_callvm_reset_mips_n32( (DCCallVM*) self );
-  return (DCCallVM*)self;
-}
-
 
 static void dc_callvm_free_mips_n32(DCCallVM* in_self)
 {
@@ -236,34 +227,37 @@
 , NULL /* callStruct */
 };
 
-static void dc_callvm_mode_mips_n32(DCCallVM* self,DCint mode)
+static void dc_callvm_mode_mips_n32(DCCallVM* in_self, DCint mode)
 {
+  DCCallVM_mips_n32* self = (DCCallVM_mips_n32*)in_self;
+  DCCallVM_vt* vt;
+
   switch(mode) {
     case DC_CALL_C_DEFAULT:
-      self->mVTpointer = &gVT_mips_n32;
+    case DC_CALL_C_MIPS64_N32:
+      vt = &gVT_mips_n32;
       break;
     case DC_CALL_C_ELLIPSIS:
-      self->mVTpointer = &gVT_mips_n32_ellipsis;
+    case DC_CALL_C_ELLIPSIS_VARARGS:
+      vt = &gVT_mips_n32_ellipsis;
       break;
     default:
-      self->mError = DC_ERROR_UNSUPPORTED_MODE;
-      break;
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return;
   }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
-DCCallVM* dcNewCallVM_mips_n32(DCsize size) 
+/* Public API. */
+DCCallVM* dcNewCallVM(DCsize size)
 {
-  return dc_callvm_new_mips_n32(&gVT_mips_n32, size);
+  DCCallVM_mips_n32* p = (DCCallVM_mips_n32*)dcAllocMem(sizeof(DCCallVM_mips_n32)+size);
+
+  dc_callvm_mode_mips_n32((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  dc_callvm_reset_mips_n32((DCCallVM*)p);
+
+  return (DCCallVM*)p;
 }
 
-DCCallVM* dcNewCallVM_mips_n32_ellipsis(DCsize size) 
-{
-  return dc_callvm_new_mips_n32(&gVT_mips_n32_ellipsis, size);
-}
-
-
-DCCallVM* dcNewCallVM(DCsize size)
-{
-  return dcNewCallVM_mips_n32(size);
-}
-
--- a/dyncall/dyncall_callvm_mips_n64.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_mips_n64.c	Wed Apr 06 00:21:51 2016 +0200
@@ -61,15 +61,6 @@
   self->mRegData.mUseDouble = 0LL;
 }
 
-static DCCallVM* dc_callvm_new_mips_n64(DCCallVM_vt* vt, DCsize size)
-{
-  DCCallVM_mips_n64* self = (DCCallVM_mips_n64*)dcAllocMem(sizeof(DCCallVM_mips_n64)+size);
-  dc_callvm_base_init(&self->mInterface, vt);
-  dcVecInit(&self->mVecHead, size);
-  dc_callvm_reset_mips_n64( (DCCallVM*) self );
-  return (DCCallVM*)self;
-}
-
 
 static void dc_callvm_free_mips_n64(DCCallVM* in_self)
 {
@@ -177,7 +168,6 @@
   dcCall_mips_n64(target, &self->mRegData, size, dcVecData(&self->mVecHead));
 }
 
-/* Forward Declaration. */
 static void dc_callvm_mode_mips_n64(DCCallVM* in_self,DCint mode);
 
 DCCallVM_vt gVT_mips_n64 =
@@ -236,34 +226,37 @@
 , NULL /* callStruct */
 };
 
-static void dc_callvm_mode_mips_n64(DCCallVM* self,DCint mode)
+static void dc_callvm_mode_mips_n64(DCCallVM* in_self, DCint mode)
 {
+  DCCallVM_mips_n64* self = (DCCallVM_mips_n64*)in_self;
+  DCCallVM_vt* vt;
+
   switch(mode) {
     case DC_CALL_C_DEFAULT:
-      self->mVTpointer = &gVT_mips_n64;
+    case DC_CALL_C_MIPS64_N64:
+      vt = &gVT_mips_n64;
       break;
     case DC_CALL_C_ELLIPSIS:
-      self->mVTpointer = &gVT_mips_n64_ellipsis;
+    case DC_CALL_C_ELLIPSIS_VARARGS:
+      vt = &gVT_mips_n64_ellipsis;
       break;
     default:
-      self->mError = DC_ERROR_UNSUPPORTED_MODE;
-      break;
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return;
   }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
-DCCallVM* dcNewCallVM_mips_n64(DCsize size) 
+/* Public API. */
+DCCallVM* dcNewCallVM(DCsize size)
 {
-  return dc_callvm_new_mips_n64(&gVT_mips_n64, size);
+  DCCallVM_mips_n64* p = (DCCallVM_mips_n64*)dcAllocMem(sizeof(DCCallVM_mips_n64)+size);
+
+  dc_callvm_mode_mips_n64((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  dc_callvm_reset_mips_n64((DCCallVM*)p);
+
+  return (DCCallVM*)p;
 }
 
-DCCallVM* dcNewCallVM_mips_n64_ellipsis(DCsize size) 
-{
-  return dc_callvm_new_mips_n64(&gVT_mips_n64_ellipsis, size);
-}
-
-
-DCCallVM* dcNewCallVM(DCsize size)
-{
-  return dcNewCallVM_mips_n64(size);
-}
-
--- a/dyncall/dyncall_callvm_mips_n64.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_mips_n64.h	Wed Apr 06 00:21:51 2016 +0200
@@ -44,8 +44,6 @@
   DCVecHead mVecHead;
 } DCCallVM_mips_n64;
 
-DCCallVM* dcNewCallVM_mips_n64(DCsize size);
-
 #ifdef __cplusplus
 }
 #endif
--- a/dyncall/dyncall_callvm_mips_o32.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_mips_o32.c	Wed Apr 06 00:21:51 2016 +0200
@@ -60,34 +60,12 @@
   self->mArgCount = 0;
 }
 
-static DCCallVM* dc_callvm_new_mips_o32(DCCallVM_vt* vt, DCsize size)
-{
-  DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)dcAllocMem(sizeof(DCCallVM_mips_o32)+size);
-  dc_callvm_base_init(&self->mInterface, vt);
-  dcVecInit(&self->mVecHead, size);
-  dc_callvm_reset_mips_o32( (DCCallVM*) self );
-  return (DCCallVM*)self;
-}
-
 
 static void dc_callvm_free_mips_o32(DCCallVM* in_self)
 {
   dcFreeMem(in_self);
 }
 
-static void dc_callvm_mode_mips_o32(DCCallVM* self, DCint mode)
-{
-  switch(mode) {
-    case DC_CALL_C_DEFAULT:
-    case DC_CALL_C_ELLIPSIS:
-    case DC_CALL_C_MIPS32_O32:
-      break;
-    default:
-      self->mError = DC_ERROR_UNSUPPORTED_MODE;
-      break;
-  }
-}
-
 /* arg int -- fillup integer register file OR push on stack */
 
 static void dc_callvm_argInt_mips_o32(DCCallVM* in_self, DCint i)
@@ -195,6 +173,8 @@
   dcCall_mips_o32(target, &self->mRegData, size, dcVecData(&self->mVecHead));
 }
 
+static void dc_callvm_mode_mips_o32(DCCallVM* in_self, DCint mode);
+
 DCCallVM_vt gVT_mips_o32 =
 {
   &dc_callvm_free_mips_o32
@@ -223,14 +203,36 @@
 , NULL /* callStruct */
 };
 
-DCCallVM* dcNewCallVM_mips_o32(DCsize size) 
+/* mode: only a single mode available currently. */
+static void dc_callvm_mode_mips_o32(DCCallVM* in_self, DCint mode)
 {
-  return dc_callvm_new_mips_o32(&gVT_mips_o32, size);
+  DCCallVM_mips_o32* self = (DCCallVM_mips_o32*)in_self;
+  DCCallVM_vt* vt;
+
+  switch(mode) {
+    case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_MIPS32_O32:
+    case DC_CALL_C_ELLIPSIS:
+    case DC_CALL_C_ELLIPSIS_VARARGS:
+      vt = &gVT_mips_o32;
+      break;
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return;
+  }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
-
+/* Public API. */
 DCCallVM* dcNewCallVM(DCsize size)
 {
-  return dcNewCallVM_mips_o32(size);
+  DCCallVM_mips_o32* p = (DCCallVM_mips_o32*)dcAllocMem(sizeof(DCCallVM_mips_o32)+size);
+
+  dc_callvm_mode_mips_o32((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  dc_callvm_reset_mips_o32((DCCallVM*)p);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_mips_o32.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_mips_o32.h	Wed Apr 06 00:21:51 2016 +0200
@@ -40,7 +40,5 @@
   DCVecHead          mVecHead;
 } DCCallVM_mips_o32;
 
-DCCallVM* dcNewCallVM_mips_o32(DCsize size);
-
 #endif /* DYNCALL_CALLVM_MIPS_O32_H */
 
--- a/dyncall/dyncall_callvm_ppc32.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_ppc32.c	Wed Apr 06 00:21:51 2016 +0200
@@ -51,11 +51,11 @@
 /* Support for Mac OS X (Darwin) and Systen V ABI for Power PC 32-bit */
 
 #if defined(DC__OS_Darwin)
-#define DC__ABI_Darwin
+#  define DC__ABI_Darwin
 #elif defined(DC__OS_Linux) || defined(DC__OS_FreeBSD) || defined(DC__OS_OpenBSD) || defined(DC__OS_NetBSD) || defined(DC__OS_DragonFlyBSD) || defined(DC__OS_SunOS)
-#define DC__ABI_SysV
+#  define DC__ABI_SysV
 #else
-#error Unsupported OS for ppc32 architecture.
+#  error Unsupported OS for ppc32 architecture.
 #endif
 
 static void dc_callvm_free_ppc32(DCCallVM* in_self)
@@ -364,29 +364,26 @@
 
 void dc_callvm_mode_ppc32(DCCallVM* in_self, DCint mode)
 {
-  DCCallVM_ppc32* self = (DCCallVM_ppc32*) in_self;
+  DCCallVM_ppc32* self = (DCCallVM_ppc32*)in_self;
   DCCallVM_vt* vt;
+
   switch(mode) {
 
-    case DC_CALL_C_PPC32_OSX:  
-
 #if defined(DC__ABI_Darwin)
     case DC_CALL_C_DEFAULT:
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
 #endif
-
+    case DC_CALL_C_PPC32_OSX:  
       vt = &gVT_ppc32_darwin; 
       break;
 
-    case DC_CALL_C_PPC32_SYSV: 
-
 #if defined(DC__ABI_SysV)
     case DC_CALL_C_DEFAULT:
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
 #endif
-
+    case DC_CALL_C_PPC32_SYSV: 
       vt = &gVT_ppc32_sysv;
       break;
 
@@ -399,17 +396,20 @@
       self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
       return;
   }
-  
+
   dc_callvm_base_init(&self->mInterface, vt);
 }
 
+/* Public API. */
 DCCallVM* dcNewCallVM(DCsize size)
 {
-  DCCallVM_ppc32* self = (DCCallVM_ppc32*)dcAllocMem(sizeof(DCCallVM_ppc32)+size);
-  dcVecInit(&self->mVecHead, size);
-  self->mIntRegs              = 0;
-  self->mFloatRegs            = 0;
-  dc_callvm_mode_ppc32( (DCCallVM*) self, DC_CALL_C_DEFAULT );
-  return (DCCallVM*)self;
+  DCCallVM_ppc32* p = (DCCallVM_ppc32*)dcAllocMem(sizeof(DCCallVM_ppc32)+size);
+
+  dc_callvm_mode_ppc32((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  dc_callvm_reset_ppc32((DCCallVM*)p);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_ppc32.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_ppc32.h	Wed Apr 06 00:21:51 2016 +0200
@@ -56,7 +56,5 @@
   DCVecHead mVecHead;
 };
 
-DCCallVM* dcNewCallVM_ppc32(DCsize size);
-
 #endif /* DYNCALL_CALLVM_PPC32_H */
 
--- a/dyncall/dyncall_callvm_ppc64.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_ppc64.c	Wed Apr 06 00:21:51 2016 +0200
@@ -345,10 +345,10 @@
 {
   DCCallVM_ppc64* self = (DCCallVM_ppc64*) in_self;
   DCCallVM_vt* vt;
+
   switch(mode) {
-
+    case DC_CALL_C_DEFAULT:
     case DC_CALL_C_PPC64: 
-    case DC_CALL_C_DEFAULT:
     case DC_CALL_C_ELLIPSIS:
 #if DC__ABI_PPC64_ELF_V == 2
       vt = &gVT_ppc64;
@@ -375,13 +375,16 @@
   dc_callvm_base_init(&self->mInterface, vt);
 }
 
+/* Public API. */
 DCCallVM* dcNewCallVM(DCsize size)
 {
-  DCCallVM_ppc64* self = (DCCallVM_ppc64*)dcAllocMem(sizeof(DCCallVM_ppc64)+size);
-  dcVecInit(&self->mVecHead, size);
-  self->mIntRegs              = 0;
-  self->mFloatRegs            = 0;
-  dc_callvm_mode_ppc64( (DCCallVM*) self, DC_CALL_C_DEFAULT );
-  return (DCCallVM*)self;
+  DCCallVM_ppc64* p = (DCCallVM_ppc64*)dcAllocMem(sizeof(DCCallVM_ppc64)+size);
+
+  dc_callvm_mode_ppc64((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  dc_callvm_reset_ppc64((DCCallVM*)p);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_ppc64.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_ppc64.h	Wed Apr 06 00:21:51 2016 +0200
@@ -54,7 +54,5 @@
   DCVecHead mVecHead;
 };
 
-DCCallVM* dcNewCallVM_ppc64(DCsize size);
-
 #endif /* DYNCALL_CALLVM_PPC64_H */
 
--- a/dyncall/dyncall_callvm_sparc.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_sparc.c	Wed Apr 06 00:21:51 2016 +0200
@@ -29,16 +29,6 @@
 #include "dyncall_utils.h"
 #include "dyncall_alloc.h"
 #define DEFAULT_STACK_ALIGN	16
-/* Construtor. */
-/* the six output registers %o0-%o5 are always loaded, thus we need to ensure the argument buffer has space for at least 24 bytes. */
-static DCCallVM* dc_callvm_new_sparc(DCCallVM_vt* vt, DCsize size)
-{
-  size=DC_MAX(size,sizeof(void*)*(6+1));
-  DCCallVM_sparc* self = (DCCallVM_sparc*) dcAllocMem(sizeof(DCCallVM_sparc)+size);
-  dc_callvm_base_init(&self->mInterface, vt);
-  dcVecInit(&self->mVecHead,size);
-  return (DCCallVM*)self;
-}
 
 /* Destructor. */
 static void dc_callvm_free_sparc(DCCallVM* in_self)
@@ -95,20 +85,6 @@
   dcVecAppend(&self->mVecHead, &x, sizeof(DCdouble));
 }
   
-/* mode: only a single mode available currently. */
-static void dc_callvm_mode_sparc(DCCallVM* in_self, DCint mode)
-{
-  switch(mode) {
-    case DC_CALL_C_DEFAULT:
-    case DC_CALL_C_ELLIPSIS:
-    case DC_CALL_C_SPARC32:
-      break;
-    default:
-      in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
-      break; 
-  }
-}
-
 /* we call directly with 'RTYPE dcCall(DCCallVM* in_self, DCpointer target)' */
 #if 0
 /* call: delegate to default call kernel */
@@ -119,6 +95,8 @@
 }
 #endif
 
+static void dc_callvm_mode_sparc(DCCallVM* in_self, DCint mode);
+
 /* CallVM virtual table. */
 DCCallVM_vt gVT_sparc =
 {
@@ -148,9 +126,37 @@
   NULL /* callStruct */
 };
 
+/* mode: only a single mode available currently. */
+static void dc_callvm_mode_sparc(DCCallVM* in_self, DCint mode)
+{
+  DCCallVM_sparc* self = (DCCallVM_sparc*)in_self;
+  DCCallVM_vt* vt;
+
+  switch(mode) {
+    case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_SPARC32:
+    case DC_CALL_C_ELLIPSIS:
+    case DC_CALL_C_ELLIPSIS_VARARGS:
+      vt = &gVT_sparc;
+      break;
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return;
+  }
+  dc_callvm_base_init(&self->mInterface, vt);
+}
+
 /* Public API. */
 DCCallVM* dcNewCallVM(DCsize size)
 {
-  return dc_callvm_new_sparc(&gVT_sparc,size);
+  /* the six output registers %o0-%o5 are always loaded, thus we need to ensure the argument buffer has space for at least 24 bytes. */
+  size = DC_MAX(size, sizeof(void*)*(6+1));
+  DCCallVM_sparc* p = (DCCallVM_sparc*)dcAllocMem(sizeof(DCCallVM_sparc)+size);
+
+  dc_callvm_mode_sparc((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_sparc.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_sparc.h	Wed Apr 06 00:21:51 2016 +0200
@@ -39,7 +39,5 @@
   DCVecHead mVecHead;	/* 8 bytes (max,size)       */
 };
 
-DCCallVM* dcNewCallVM_sparc(DCsize size);
-
 #endif /* DYNCALL_CALLVM_SPARC_H */
 
--- a/dyncall/dyncall_callvm_sparc64.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_sparc64.c	Wed Apr 06 00:21:51 2016 +0200
@@ -37,22 +37,12 @@
 static void dc_callvm_reset_sparc64(DCCallVM* in_self)
 {
   DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
-  dcVecResize(&self->mVecHead,DHEAD);
+  dcVecResize(&self->mVecHead, DHEAD);
   self->mIntRegs        = 0;
   self->mFloatRegs      = 0;
   self->mUseSingleFlags = 0;
 }
 
-/* Construtor. */
-/* the six output registers %o0-%o5 are always loaded, thus we need to ensure the argument buffer has space for at least 24 bytes. */
-static DCCallVM* dc_callvm_new_sparc64(DCCallVM_vt* vt, DCsize size)
-{
-  DCCallVM_sparc64* self = (DCCallVM_sparc64*) dcAllocMem(sizeof(DCCallVM_sparc64)+DHEAD+size);
-  dc_callvm_base_init(&self->mInterface, vt);
-  dcVecInit(&self->mVecHead,DHEAD+size);
-  dc_callvm_reset_sparc64(&self->mInterface);
-  return (DCCallVM*)self;
-}
 
 /* Destructor. */
 static void dc_callvm_free_sparc64(DCCallVM* in_self)
@@ -138,6 +128,21 @@
 }
 #endif
 
+#if 0
+/* Load integer 32-bit. */
+static void dc_callvm_argInt_sparc64(DCCallVM* in_self, DCint x)
+{
+  DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
+  dcVecAppend(&self->mVecHead, &x, sizeof(DCint));
+}
+
+/* we propagate Bool,Char,Short,Int to LongLong. */
+
+static void dc_callvm_argBool_sparc64(DCCallVM* in_self, DCbool x)   { dc_callvm_argInt_sparc64(in_self, (DCint)x); }
+static void dc_callvm_argChar_sparc64(DCCallVM* in_self, DCchar x)   { dc_callvm_argInt_sparc64(in_self, (DCint)x); }
+static void dc_callvm_argShort_sparc64(DCCallVM* in_self, DCshort x) { dc_callvm_argInt_sparc64(in_self, (DCint)x); }
+#endif
+
 static void dc_callvm_mode_sparc64(DCCallVM* in_self, DCint mode);
 
 DCCallVM_vt gVT_sparc64_ellipsis = 
@@ -200,40 +205,36 @@
 /* mode: only a single mode available currently. */
 static void dc_callvm_mode_sparc64(DCCallVM* in_self, DCint mode)
 {
+  DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
+  DCCallVM_vt* vt;
+
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_SPARC64:
     case DC_CALL_C_ELLIPSIS:
-    case DC_CALL_C_SPARC64:
-      in_self->mVTpointer = &gVT_sparc64; 
+      vt = &gVT_sparc64;
       break;
     case DC_CALL_C_ELLIPSIS_VARARGS:
-      in_self->mVTpointer = &gVT_sparc64_ellipsis; 
+      vt = &gVT_sparc64_ellipsis;
       break;
     default:
-      in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
-      break; 
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return;
   }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
-
 /* Public API. */
 DCCallVM* dcNewCallVM(DCsize size)
 {
-  return dc_callvm_new_sparc64(&gVT_sparc64,size);
+  /* output registers %o0-%o5 are always loaded, thus we need to ensure the argument buffer has space for at least DHEAD bytes. */
+  DCCallVM_sparc64* p = (DCCallVM_sparc64*)dcAllocMem(sizeof(DCCallVM_sparc64)+DHEAD+size);
+
+  dc_callvm_mode_sparc64((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead,DHEAD+size);
+  dc_callvm_reset_sparc64(&p->mInterface);
+
+  return (DCCallVM*)p;
 }
 
-#if 0
-/* Load integer 32-bit. */
-static void dc_callvm_argInt_sparc64(DCCallVM* in_self, DCint x)
-{
-  DCCallVM_sparc64* self = (DCCallVM_sparc64*)in_self;
-  dcVecAppend(&self->mVecHead, &x, sizeof(DCint));
-}
-
-/* we propagate Bool,Char,Short,Int to LongLong. */
-
-static void dc_callvm_argBool_sparc64(DCCallVM* in_self, DCbool x)   { dc_callvm_argInt_sparc64(in_self, (DCint)x); }
-static void dc_callvm_argChar_sparc64(DCCallVM* in_self, DCchar x)   { dc_callvm_argInt_sparc64(in_self, (DCint)x); }
-static void dc_callvm_argShort_sparc64(DCCallVM* in_self, DCshort x) { dc_callvm_argInt_sparc64(in_self, (DCint)x); }
-#endif
-
--- a/dyncall/dyncall_callvm_sparc64.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_sparc64.h	Wed Apr 06 00:21:51 2016 +0200
@@ -40,9 +40,5 @@
   DCVecHead    mVecHead;        /* 36:16, 28 => 40 */
 };
 
-DCCallVM* dcNewCallVM_sparc64(DCsize size);
-
 #endif /* DYNCALL_CALLVM_SPARC64_H */
 
-
-
--- a/dyncall/dyncall_callvm_sparc_v9.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_sparc_v9.c	Wed Apr 06 00:21:51 2016 +0200
@@ -32,18 +32,9 @@
 static void dc_callvm_reset_v9(DCCallVM* in_self)
 {
   DCCallVM_v9* self = (DCCallVM_v9*)in_self;
-  dcVecResize(&self->mVecHead,0);
+  dcVecResize(&self->mVecHead, 0);
 }
 
-/* Construtor. */
-static DCCallVM* dc_callvm_new_v9(DCCallVM_vt* vt, DCsize size)
-{
-  DCCallVM_v9* self = (DCCallVM_v9*) dcAllocMem(sizeof(DCCallVM_v9)+size);
-  dc_callvm_base_init(&self->mInterface, vt);
-  dcVecInit(&self->mVecHead,size);
-  dc_callvm_reset_v9(&self->mInterface);
-  return (DCCallVM*)self;
-}
 
 /* Destructor. */
 static void dc_callvm_free_v9(DCCallVM* in_self)
@@ -158,25 +149,35 @@
 /* mode: only a single mode available currently. */
 static void dc_callvm_mode_v9(DCCallVM* in_self, DCint mode)
 {
+  DCCallVM_v9* self = (DCCallVM_v9*)in_self;
+  DCCallVM_vt* vt;
+
   switch(mode) {
     case DC_CALL_C_DEFAULT:
+    case DC_CALL_C_SPARC64:
     case DC_CALL_C_ELLIPSIS:
-    case DC_CALL_C_SPARC64:
-      in_self->mVTpointer = &gVT_v9; 
+      vt = &gVT_v9;
       break;
     case DC_CALL_C_ELLIPSIS_VARARGS:
-      in_self->mVTpointer = &gVT_v9_ellipsis; 
+      vt = &gVT_v9_ellipsis;
       break;
     default:
-      in_self->mError = DC_ERROR_UNSUPPORTED_MODE;
-      break; 
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return; 
   }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
-
 /* Public API. */
 DCCallVM* dcNewCallVM(DCsize size)
 {
-  return dc_callvm_new_v9(&gVT_v9,size);
+  DCCallVM_v9* p = (DCCallVM_v9*)dcAllocMem(sizeof(DCCallVM_v9)+size);
+
+  dc_callvm_mode_v9((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead,size);
+  dc_callvm_reset_v9(&p->mInterface);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_sparc_v9.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_sparc_v9.h	Wed Apr 06 00:21:51 2016 +0200
@@ -32,15 +32,11 @@
 
 typedef struct 
 {
-  DCCallVM     mInterface;	/*   0: +12:8 = 16*/
+  DCCallVM     mInterface;      /*   0: +12:8 = 16*/
   DCVecHead    mVecHead;        /* 16   152: mTotalSize +8 */
                                 /* 24   160: mSize      +8 */
                                 /* 32  168: mData  */ 
 } DCCallVM_v9;
 
-DCCallVM* dcNewCallVM_v9(DCsize size);
-
 #endif /* DYNCALL_CALLVM_SPARC_V9_H */
 
-
-
--- a/dyncall/dyncall_callvm_x64.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_x64.c	Wed Apr 06 00:21:51 2016 +0200
@@ -33,23 +33,6 @@
 #include "dyncall_alloc.h"
 #include "dyncall_struct.h"
 
-static DCCallVM* dc_callvm_new_x64(DCCallVM_vt* vt, DCsize size)
-{
-  DCCallVM_x64* self = (DCCallVM_x64*)dcAllocMem(sizeof(DCCallVM_x64)+size);
-  
-  dc_callvm_base_init(&self->mInterface, vt);
-
-  /* Since we store register parameters in DCCallVM_x64 directly, adjust the stack size. */
-  size -= sizeof(DCRegData_x64);
-  size = (((signed long)size) < 0) ? 0 : size;
-
-
-  self->mRegCount.i = self->mRegCount.f =  0;
-
-  dcVecInit(&self->mVecHead, size);
-  return (DCCallVM*)self;
-}
-
 
 static void dc_callvm_free_x64(DCCallVM* in_self)
 {
@@ -61,20 +44,7 @@
 {
   DCCallVM_x64* self = (DCCallVM_x64*)in_self;
   dcVecReset(&self->mVecHead);
-  self->mRegCount.i = self->mRegCount.f =  0;
-}
-
-
-static void dc_callvm_mode_x64(DCCallVM* self, DCint mode)
-{
-  switch(mode) {
-    case DC_CALL_C_DEFAULT:
-    case DC_CALL_C_ELLIPSIS:
-      break;
-    default:
-      self->mError = DC_ERROR_UNSUPPORTED_MODE;
-      break;
-  }
+  self->mRegCount.i = self->mRegCount.f = 0;
 }
 
 
@@ -188,6 +158,8 @@
 }
 
 
+static void dc_callvm_mode_x64(DCCallVM* in_self, DCint mode);
+
 DCCallVM_vt gVT_x64 =
 {
   &dc_callvm_free_x64
@@ -216,14 +188,43 @@
 , NULL /* callStruct */
 };
 
+/* mode: only a single mode available currently. */
+static void dc_callvm_mode_x64(DCCallVM* in_self, DCint mode)
+{
+  DCCallVM_x64* self = (DCCallVM_x64*)in_self;
+  DCCallVM_vt* vt;
 
-DCCallVM* dcNewCallVM_x64(DCsize size) 
-{
-  return dc_callvm_new_x64(&gVT_x64, size);
+  switch(mode) {
+    case DC_CALL_C_DEFAULT:
+#if defined(DC_UNIX)
+    case DC_CALL_C_X64_SYSV:
+#else
+    case DC_CALL_C_X64_WIN64:
+#endif
+    case DC_CALL_C_ELLIPSIS:
+    case DC_CALL_C_ELLIPSIS_VARARGS:
+      vt = &gVT_x64;
+      break;
+    default:
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; 
+      return;
+  }
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
+/* Public API. */
 DCCallVM* dcNewCallVM(DCsize size)
 {
-  return dcNewCallVM_x64(size);
+  DCCallVM_x64* p = (DCCallVM_x64*)dcAllocMem(sizeof(DCCallVM_x64)+size);
+
+  dc_callvm_mode_x64((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  /* Since we store register parameters in DCCallVM_x64 directly, adjust the stack size. */
+  size -= sizeof(DCRegData_x64);
+  size = (((signed long)size) < 0) ? 0 : size;
+  dcVecInit(&p->mVecHead, size);
+  dc_callvm_reset_x64((DCCallVM*)p);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_x64.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_x64.h	Wed Apr 06 00:21:51 2016 +0200
@@ -105,8 +105,5 @@
   DCVecHead      mVecHead;    /* Parameters to be pushed onto stack.                     */
 } DCCallVM_x64;
 
-DCCallVM* dcNewCallVM_x64(DCsize size);
-
-
 #endif /* DYNCALL_CALLVM_X64_H */
 
--- a/dyncall/dyncall_callvm_x86.c	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_x86.c	Wed Apr 06 00:21:51 2016 +0200
@@ -31,19 +31,6 @@
 
 void dc_callvm_mode_x86(DCCallVM* in_self, DCint mode);
 
-/* call vm allocator */
-
-static DCCallVM* dc_callvm_new_x86(DCCallVM_vt* vt, DCsize size)
-{
-  DCCallVM_x86* self = (DCCallVM_x86*) dcAllocMem( sizeof(DCCallVM_x86)+size );
-
-  dc_callvm_base_init(&self->mInterface, vt);
-
-  self->mIntRegs              = 0;
-  dcVecInit(&self->mVecHead, size);
-  return (DCCallVM*) self;
-}
-
 /* call vm destructor */
 
 static void dc_callvm_free_x86(DCCallVM* in_self)
@@ -186,11 +173,6 @@
 , NULL /* callStruct */
 };
 
-DCCallVM* dcNewCallVM_x86_plan9(DCsize size) 
-{ 
-  return dc_callvm_new_x86( &gVT_x86_plan9, size );
-}
-
 
 #else
 
@@ -231,11 +213,6 @@
 , NULL /* callStruct */
 };
 
-DCCallVM* dcNewCallVM_x86_cdecl(DCsize size) 
-{ 
-  return dc_callvm_new_x86( &gVT_x86_cdecl, size );
-}
-
 
 
 /* --- stdcall -------------------------------------------------------------- */
@@ -278,12 +255,6 @@
 , NULL /* callStruct */
 };
 
-/* win32/std callvm allocator */
-
-DCCallVM* dcNewCallVM_x86_win32_std(DCsize size) 
-{ 
-  return dc_callvm_new_x86( &gVT_x86_win32_std, size );
-}
 
 /* --- fastcall common (ms/gnu) -------------------------------------------- */
 
@@ -389,10 +360,6 @@
 , NULL /* callStruct */
 };
 
-DCCallVM* dcNewCallVM_x86_win32_fast_ms(DCsize size) 
-{ 
-  return dc_callvm_new_x86( &gVT_x86_win32_fast_ms, size );
-}
 
 /* --- gnu fastcall -------------------------------------------------------- */
 
@@ -487,10 +454,6 @@
 , NULL /* callStruct */
 };
 
-DCCallVM* dcNewCallVM_x86_win32_fast_gnu(DCsize size) 
-{ 
-  return dc_callvm_new_x86( &gVT_x86_win32_fast_gnu, size );
-}
 
 /* --- this ms ------------------------------------------------------------- */
 
@@ -605,13 +568,6 @@
 };
 
 
-/* win32/this/ms callvm allocator */
-
-DCCallVM* dcNewCallVM_x86_win32_this_ms(DCsize size) 
-{ 
-  return dc_callvm_new_x86( &gVT_x86_win32_this_ms, size );
-}
-
 #endif
 
 
@@ -619,13 +575,15 @@
 
 void dc_callvm_mode_x86(DCCallVM* in_self, DCint mode)
 {
-  DCCallVM_x86* self = (DCCallVM_x86*) in_self;
-  DCCallVM_vt*  vt;
+  DCCallVM_x86* self = (DCCallVM_x86*)in_self;
+  DCCallVM_vt* vt;
+
   switch(mode) {
+    case DC_CALL_C_DEFAULT:
     case DC_CALL_C_ELLIPSIS:
     case DC_CALL_C_ELLIPSIS_VARARGS:
-    case DC_CALL_C_DEFAULT:
-#if defined(DC_PLAN9) /* Plan9 (and forks) have their own calling convention (and no support for foreign ones). */
+/* Plan9 (and forks) have their own calling convention (and no support for foreign ones). */
+#if defined(DC_PLAN9)
     case DC_CALL_C_X86_PLAN9:          vt = &gVT_x86_plan9;          break;
 #else
     case DC_CALL_C_X86_CDECL:          vt = &gVT_x86_cdecl;          break;
@@ -639,30 +597,31 @@
 #   if defined DC__OS_Linux
       vt = &gVT_x86_sys_int80h_linux; break;
 #   else
-      vt = &gVT_x86_sys_int80h_bsd; break;
+      vt = &gVT_x86_sys_int80h_bsd;   break;
 #   endif
 # else
       self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return;
 # endif
-    case DC_CALL_SYS_X86_INT80H_LINUX:
-      vt = &gVT_x86_sys_int80h_linux; break;
-    case DC_CALL_SYS_X86_INT80H_BSD:
-      vt = &gVT_x86_sys_int80h_bsd; break;
+    case DC_CALL_SYS_X86_INT80H_LINUX: vt = &gVT_x86_sys_int80h_linux; break;
+    case DC_CALL_SYS_X86_INT80H_BSD:   vt = &gVT_x86_sys_int80h_bsd;   break;
 #endif
     default: 
-      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE; return;
+      self->mInterface.mError = DC_ERROR_UNSUPPORTED_MODE;
+      return;
   }
-  self->mInterface.mVTpointer = vt;
+  dc_callvm_base_init(&self->mInterface, vt);
 }
 
-/* new */
-
+/* Public API. */
 DCCallVM* dcNewCallVM(DCsize size)
 {
-#if defined(DC__OS_Plan9)
-  return dcNewCallVM_x86_plan9(size);
-#else
-  return dcNewCallVM_x86_cdecl(size);
-#endif
+  DCCallVM_x86* p = (DCCallVM_x86*)dcAllocMem(sizeof(DCCallVM_x86)+size);
+
+  dc_callvm_mode_x86((DCCallVM*)p, DC_CALL_C_DEFAULT);
+
+  dcVecInit(&p->mVecHead, size);
+  dc_callvm_reset_x86((DCCallVM*)p);
+
+  return (DCCallVM*)p;
 }
 
--- a/dyncall/dyncall_callvm_x86.h	Mon Mar 28 23:46:59 2016 +0200
+++ b/dyncall/dyncall_callvm_x86.h	Wed Apr 06 00:21:51 2016 +0200
@@ -56,21 +56,5 @@
   DCVecHead mVecHead;
 };
 
-/* Plan9 has no support for OS foreign calling conventions at
-   the time, and vice-versa. */
-#if defined(DC__OS_Plan9)
-
-DCCallVM* dcNewCallVM_x86_plan9(DCsize size);
-
-#else
-
-DCCallVM* dcNewCallVM_x86_cdecl(DCsize size);
-DCCallVM* dcNewCallVM_x86_win32_std(DCsize size);
-DCCallVM* dcNewCallVM_x86_win32_fast_ms(DCsize size);
-DCCallVM* dcNewCallVM_x86_win32_fast_gnu(DCsize size);
-DCCallVM* dcNewCallVM_x86_win32_this_ms(DCsize size);
-
-#endif
-
 #endif /* DYNCALL_CALLVM_X86_H */