Repository: swig/swig (language: cpp)

Issue:
[JavaScript] void * does not match any kind of pointer
``` c++
%inline %{ 
    void foo(void * bar) {} 
%}
```

When calling `foo` from JavaScript, I get the error message `in method 'foo', argument 1 of type 'void *'`.

I think that changing the line 218 of `v8/javascriptrun.swg` and the line 123 of `jsc/javascriptrun.swg` to the following might fix the bug...

``` c++
if(info && cdata->info != info)
```

In the meantime, here is a possible workaround:

``` c++
%inline %{
    typedef void * void_ptr;
%}

%typemap(in,noblock=1) void_ptr (int res) {
    res = SWIG_GetInstancePtr($input, %as_voidptrptr(&$1));
    if (!SWIG_IsOK(res)) { 
        %argument_fail(res, "$type", $symname, $argnum); 
    }
}

%inline %{ 
    void foo(void_ptr bar) {} 
%}
```



Discussion / hints:

Fix patch:
diff --git a/CHANGES.current b/CHANGES.current
index 90dcbcb9477..68061002b5c 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
 Version 4.1.0 (in progress)
 ===========================
 
+2022-03-07: olly
+	    [Javascript] #682 Fix handling of functions which take void*.
+
 2022-03-06: olly
 	    SWIG should now reliably exit with status 0 if the run was
 	    successful and status 1 if there was an error (or a warning and
diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg
index d092ea4ab0f..20e74787244 100644
--- a/Lib/javascript/jsc/javascriptrun.swg
+++ b/Lib/javascript/jsc/javascriptrun.swg
@@ -122,7 +122,7 @@ SWIGRUNTIME int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef ob
   }
   assert(ptr);
   *ptr = NULL;
-  if (cdata->info == info) {
+  if (!info || cdata->info == info) {
     *ptr = cdata->swigCObject;
   } else {
     swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info);
diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg
index 518b19a8fda..7e50a8b84d3 100644
--- a/Lib/javascript/v8/javascriptrun.swg
+++ b/Lib/javascript/v8/javascriptrun.swg
@@ -178,7 +178,7 @@ SWIGRUNTIME int SWIG_V8_ConvertInstancePtr(SWIGV8_OBJECT objRef, void **ptr, swi
   if(cdata == NULL) {
     return SWIG_ERROR;
   }
-  if(cdata->info != info) {
+  if(info && cdata->info != info) {
     swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info);
     if (!tc && cdata->info->name) {
       tc = SWIG_TypeCheck(cdata->info->name, info);


Test patch:
diff --git a/Examples/test-suite/javascript/voidtest_runme.js b/Examples/test-suite/javascript/voidtest_runme.js
new file mode 100644
index 00000000000..8ff0c0ba9a3
--- /dev/null
+++ b/Examples/test-suite/javascript/voidtest_runme.js
@@ -0,0 +1,28 @@
+var voidtest = require("voidtest");
+
+voidtest.globalfunc();
+var f = new voidtest.Foo();
+f.memberfunc();
+
+voidtest.Foo.staticmemberfunc();
+
+if (f.memberfunc() !== (function(){}())) {
+  throw new Error("f.memberfunc() didn't return same result as pure Javascript equivalent");
+}
+
+v1 = voidtest.vfunc1(f);
+v2 = voidtest.vfunc2(f);
+if (!voidtest.test_pointers_equal(v1, v2)) {
+  throw new Error("!voidtest.test_pointers_equal(v1, v2)");
+}
+
+v3 = voidtest.vfunc3(v1);
+if (!voidtest.test_pointers_equal(v3.get_this(), f.get_this())) {
+  throw new Error("!voidtest.test_pointers_equal(v3.get_this(), f.get_this())");
+}
+v4 = voidtest.vfunc1(f);
+if (!voidtest.test_pointers_equal(v4, v1)) {
+  throw new Error("!voidtest.test_pointers_equal(v4, v1)");
+}
+
+v3.memberfunc();
diff --git a/Examples/test-suite/voidtest.i b/Examples/test-suite/voidtest.i
index f0e64937327..d792f415199 100644
--- a/Examples/test-suite/voidtest.i
+++ b/Examples/test-suite/voidtest.i
@@ -9,6 +9,7 @@ class Foo {
 public:
    Foo(void) { }
    void memberfunc(void) { }
+   void* get_this() { return this; }
    static void staticmemberfunc(void) { }
 };
 
@@ -18,4 +19,6 @@ void *vfunc2(Foo *f) { return f; }
 Foo  *vfunc3(void *f) { return (Foo *) f; }
 Foo  *vfunc4(Foo *f) { return f; }
 
+bool test_pointers_equal(void *a, void *b) { return a == b; }
+
 %}