OUTPUT typemaps on methods that don't return void

SWIGJSC_ValueIsArray could be implemented by JSValueIsArray in later
versions of Javascript webkit, similar fix to previous commits for v8.

Enhance testing of OUTPUT typemaps to test more than one output.
This commit is contained in:
William S Fulton 2021-03-01 14:20:18 +00:00
parent 5ed74fd19b
commit 4b64becbbb
5 changed files with 38 additions and 6 deletions

View File

@ -10,7 +10,7 @@ function check_array(a, b) {
if (a.length != b.length)
throw new Error("Array length mismatch " + a.length + " " + b.length)
if (!a.every(function(element, index) { return element === b[index]; }))
throw new Error("Arrays don't match a: " + a + " b:" + b)
throw new Error("Arrays don't match a:" + a + " b:" + b)
}
// Check double INPUT typemaps
@ -47,3 +47,4 @@ check_array(li_typemaps.inoutr_int2(1,2), [1, 2])
fi = li_typemaps.out_foo(10)
check(fi[0].a, 10)
check(fi[1], 20)
check(fi[2], 30)

View File

@ -2,6 +2,7 @@
%include "typemaps.i"
%apply int *OUTPUT { int *OUTPUT2 };
%apply int &INOUT { int &INOUT2 };
%newobject out_foo;
%inline %{
@ -51,10 +52,13 @@ void out_longlong(long long x, long long *OUTPUT) { *OUTPUT = x; }
void out_ulonglong(unsigned long long x, unsigned long long *OUTPUT) { *OUTPUT = x; }
/* Tests a returning a wrapped pointer and an output argument */
struct Foo *out_foo(int a, int *OUTPUT) {
struct Foo *out_foo(int a, int *OUTPUT, int *OUTPUT2) {
struct Foo *f = new struct Foo();
f->a = a;
*OUTPUT = a * 2;
struct Foo *f2 = new struct Foo();
f2->a = a;
*OUTPUT2 = a * 3;
return f;
}

View File

@ -38,5 +38,5 @@ assert(li_typemaps.inoutr_bool(false)==false)
a,b=li_typemaps.inoutr_int2(1,2)
assert(a==1 and b==2)
f,i=li_typemaps.out_foo(10)
assert(f.a==10 and i==20)
f,i,i2=li_typemaps.out_foo(10)
assert(f.a==10 and i==20 and i2==30)

View File

@ -1,7 +1,7 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 415;
use Test::More tests => 416;
BEGIN { use_ok('li_typemaps') }
require_ok('li_typemaps');
@ -75,10 +75,11 @@ SKIP: {
batch('ulonglong', $c);
}
my($foo, $int) = li_typemaps::out_foo(10);
my($foo, $int, $int2) = li_typemaps::out_foo(10);
isa_ok($foo, 'li_typemaps::Foo');
is($foo->{a}, 10);
is($int, 20);
is($int2, 30);
my($a, $b) = li_typemaps::inoutr_int2(13, 31);
is($a, 13);

View File

@ -317,6 +317,30 @@ unsigned int SWIGJSC_ArrayLength(JSContextRef context, JSObjectRef arr) {
}
}
SWIGRUNTIME
bool SWIGJSC_ValueIsArray(JSContextRef context, JSValueRef value) {
if (JSValueIsObject(context, value)) {
static JSStringRef ArrayString = NULL;
static JSStringRef isArrayString = NULL;
JSObjectRef array = NULL;
JSObjectRef isArray = NULL;
JSValueRef retval = NULL;
if (!ArrayString)
ArrayString = JSStringCreateWithUTF8CString("Array");
if (!isArrayString)
isArrayString = JSStringCreateWithUTF8CString("isArray");
array = (JSObjectRef)JSObjectGetProperty(context, JSContextGetGlobalObject(context), ArrayString, NULL);
isArray = (JSObjectRef)JSObjectGetProperty(context, array, isArrayString, NULL);
retval = JSObjectCallAsFunction(context, isArray, NULL, 1, &value, NULL);
if (JSValueIsBoolean(context, retval))
return JSValueToBoolean(context, retval);
}
return false;
}
SWIGRUNTIME
JSValueRef SWIGJSC_AppendOutput(JSContextRef context, JSValueRef value, JSValueRef obj) {
JSObjectRef arr;
@ -324,6 +348,8 @@ JSValueRef SWIGJSC_AppendOutput(JSContextRef context, JSValueRef value, JSValueR
if (JSValueIsUndefined(context, value)) {
arr = JSObjectMakeArray(context, 0, 0, 0);
} else if (!SWIGJSC_ValueIsArray(context, value)) {
arr = JSObjectMakeArray(context, 1, &value, 0);
} else {
arr = JSValueToObject(context, value, 0);
}