diff --git a/.gitignore b/.gitignore index 5df510547..0006e6ef6 100644 --- a/.gitignore +++ b/.gitignore @@ -150,6 +150,8 @@ Examples/guile/*/my-guile # Java Examples/test-suite/java/*/ +Examples/test-suite/java/expected.txt +Examples/test-suite/java/got.txt Examples/java/*/*.java !Examples/java/*/runme.java Examples/java/doxygen/javadocs diff --git a/CHANGES.current b/CHANGES.current index b7cc4b1ea..c20d3640d 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) =========================== +2021-03-06: nshmyrev + #872 [Javascript] Various typemap issues in arrays_javascript.i fixed. + 2021-03-03: vaughamhong #577 [Javascript] Implemented SetModule/GetModule for JSC to allow type sharing across modules. diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index fed028388..93602a434 100644 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -16,6 +16,9 @@ top_builddir = @top_builddir@ C_TEST_CASES += \ ccomplextest \ +CPP_TEST_CASES += \ + javascript_lib_arrays \ + SWIGEXE = $(top_builddir)/swig SWIG_LIB_DIR = $(top_srcdir)/Lib diff --git a/Examples/test-suite/javascript/javascript_lib_arrays_runme.js b/Examples/test-suite/javascript/javascript_lib_arrays_runme.js new file mode 100644 index 000000000..1eb586134 --- /dev/null +++ b/Examples/test-suite/javascript/javascript_lib_arrays_runme.js @@ -0,0 +1,20 @@ +var javascript_lib_arrays = require("javascript_lib_arrays"); + +var arr = [1, 2, 3, 4, 5]; + +function check(a, b) { + if (a !== b) { + throw new Error("Not equal: " + a + " " + b) + } +} + +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) +} + +check(15, javascript_lib_arrays.sum1(arr, arr.length)); +check(6, javascript_lib_arrays.sum2(arr)); +check_array([1, 2, 3, 4], javascript_lib_arrays.data3) diff --git a/Examples/test-suite/javascript_lib_arrays.i b/Examples/test-suite/javascript_lib_arrays.i new file mode 100644 index 000000000..512084ad5 --- /dev/null +++ b/Examples/test-suite/javascript_lib_arrays.i @@ -0,0 +1,30 @@ +%module javascript_lib_arrays + +%include + +%apply int[] { int *data1 } +%apply int[3] { int data2[3] } +%apply int[4] { int data3[4] } + +%inline %{ + +int sum1(int *data1, int size) { + int sum = 0; + for (int i = 0; i < size; i++) { + sum += data1[i]; + } + return sum; +} + +int sum2(int data2[3]) { + int sum = 0; + for (int i = 0; i < 3; i++) { + sum += data2[i]; + } + return sum; +} + +int data3[4] = {1, 2, 3, 4}; + +%} + diff --git a/Lib/javascript/jsc/arrays_javascript.i b/Lib/javascript/jsc/arrays_javascript.i index b9199d86b..713b7ef23 100644 --- a/Lib/javascript/jsc/arrays_javascript.i +++ b/Lib/javascript/jsc/arrays_javascript.i @@ -21,34 +21,39 @@ * fs = example.FiddleSticks; * ----------------------------------------------------------------------------- */ -%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} + +%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} %fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {} +%fragment("SWIG_JSCOutInt", "header", fragment=SWIG_From_frag(int)) {} +%fragment("SWIG_JSCOutNumber", "header", fragment=SWIG_From_frag(double)) {} -%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY] - (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) { +%define JAVASCRIPT_ARRAYS_IN_DECL(NAME, CTYPE, ANY, ANYLENGTH) + +%typemap(in, fragment=NAME) CTYPE[ANY] { if (JSValueIsObject(context, $input)) { + int i; // Convert into Array - array = JSValueToObject(context, $input, NULL); + JSObjectRef array = JSValueToObject(context, $input, NULL); - length = $1_dim0; + int length = ANYLENGTH; $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); // Get each element from array for (i = 0; i < length; i++) { - jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL); + JSValueRef jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL); + $*1_ltype temp; // Get primitive value from JSObject - res = SWIG_AsVal(int)(jsvalue, &temp); + int res = SWIG_AsVal(CTYPE)(jsvalue, &temp); if (!SWIG_IsOK(res)) { SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); } arg$argnum[i] = temp; } - } else { @@ -56,68 +61,34 @@ } } -%typemap(freearg) int[], int[ANY] { +%typemap(freearg) CTYPE[ANY] { free($1); } -%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0) -{ - length = $1_dim0; +%enddef + +%define JAVASCRIPT_ARRAYS_OUT_DECL(NAME, CTYPE) + +%typemap(out, fragment=NAME) CTYPE[ANY] { + int length = $1_dim0; JSValueRef values[length]; + int i; for (i = 0; i < length; i++) { - values[i] = SWIG_From(int)($1[i]); + values[i] = SWIG_From(CTYPE)($1[i]); } $result = JSObjectMakeArray(context, length, values, NULL); } -%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY] - (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) { - if (JSValueIsObject(context, $input)) - { - // Convert into Array - array = JSValueToObject(context, $input, NULL); +%enddef - length = $1_dim0; +JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetIntProperty", int, , SWIGJSC_ArrayLength(context, array)) +JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetIntProperty", int, ANY, $1_dim0) +JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetNumberProperty", double, , SWIGJSC_ArrayLength(context, array)) +JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetNumberProperty", double, ANY, $1_dim0) - $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); +JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_JSCOutInt", int) +JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_JSCOutNumber", double) - // Get each element from array - for (i = 0; i < length; i++) - { - jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL); - - // Get primitive value from JSObject - res = SWIG_AsVal(double)(jsvalue, &temp); - if (!SWIG_IsOK(res)) - { - SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); - } - arg$argnum[i] = temp; - } - - } - else - { - SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); - } -} - -%typemap(freearg) double[], double[ANY] { - free($1); -} - -%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0) -{ - length = $1_dim0; - JSValueRef values[length]; - - for (i = 0; i < length; i++) - { - values[i] = SWIG_From(double)($1[i]); - } - - $result = JSObjectMakeArray(context, length, values, NULL); -} diff --git a/Lib/javascript/v8/arrays_javascript.i b/Lib/javascript/v8/arrays_javascript.i index 22b50be8f..6dc7e4b9b 100644 --- a/Lib/javascript/v8/arrays_javascript.i +++ b/Lib/javascript/v8/arrays_javascript.i @@ -21,105 +21,66 @@ * fs = example.FiddleSticks; * ----------------------------------------------------------------------------- */ -%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} + +%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} %fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {} +%fragment("SWIG_JSCOutInt", "header", fragment=SWIG_From_frag(int)) {} +%fragment("SWIG_JSCOutNumber", "header", fragment=SWIG_From_frag(double)) {} -%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY] - (int length = 0, v8::Local array, v8::Local jsvalue, int i = 0, int res = 0, $*1_ltype temp) { - if ($input->IsArray()) - { +%define JAVASCRIPT_ARRAYS_IN_DECL(NAME, CTYPE, ANY, ANYLENGTH) + +%typemap(in, fragment=NAME) CTYPE[ANY] { + if ($input->IsArray()) { // Convert into Array - array = v8::Local::Cast($input); + v8::Local array = v8::Local::Cast($input); - length = $1_dim0; + int length = ANYLENGTH; - $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); // Get each element from array - for (i = 0; i < length; i++) - { - jsvalue = array->Get(i); + for (int i = 0; i < length; i++) { + v8::Local jsvalue = SWIGV8_ARRAY_GET(array, i); + $*1_ltype temp; // Get primitive value from JSObject - res = SWIG_AsVal(int)(jsvalue, &temp); - if (!SWIG_IsOK(res)) - { + int res = SWIG_AsVal(CTYPE)(jsvalue, &temp); + if (!SWIG_IsOK(res)) { SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); } arg$argnum[i] = temp; } - - } - else - { - SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } else { + SWIG_exception_fail(SWIG_ERROR, "$input is not an array"); } } -%typemap(freearg) int[], int[ANY] { - free($1); +%typemap(freearg) CTYPE[ANY] { + free($1); } -%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0) -{ - length = $1_dim0; - v8::Local array = v8::Array::New(length); +%enddef - for (i = 0; i < length; i++) - { - array->Set(i, SWIG_From(int)($1[i])); +%define JAVASCRIPT_ARRAYS_OUT_DECL(NAME, CTYPE) + +%typemap(out, fragment=NAME) CTYPE[ANY] { + int length = $1_dim0; + v8::Local array = SWIGV8_ARRAY_NEW(length); + + for (int i = 0; i < length; i++) { + SWIGV8_ARRAY_SET(array, i, SWIG_From(CTYPE)($1[i])); } - $result = array; } -%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY] - (int length = 0, v8::Local array, v8::Local jsvalue, int i = 0, int res = 0, $*1_ltype temp) { - if ($input->IsArray()) - { - // Convert into Array - array = v8::Local::Cast($input); +%enddef - length = $1_dim0; +JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetIntProperty", int, , array->Length()) +JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetIntProperty", int, ANY, $1_dim0) +JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetNumberProperty", double, , array->Length()) +JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetNumberProperty", double, ANY, $1_dim0) - $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); +JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_JSCOutInt", int) +JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_JSCOutNumber", double) - // Get each element from array - for (i = 0; i < length; i++) - { - jsvalue = array->Get(i); - - // Get primitive value from JSObject - res = SWIG_AsVal(double)(jsvalue, &temp); - if (!SWIG_IsOK(res)) - { - SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); - } - arg$argnum[i] = temp; - } - - } - else - { - SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); - } -} - -%typemap(freearg) double[], double[ANY] { - free($1); -} - -%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0) -{ - length = $1_dim0; - v8::Local array = v8::Array::New(length); - - for (i = 0; i < length; i++) - { - array->Set(i, SWIG_From(double)($1[i])); - } - - - $result = array; -} diff --git a/Lib/javascript/v8/javascriptcomplex.swg b/Lib/javascript/v8/javascriptcomplex.swg index b73d5e2dd..7b3c5547e 100644 --- a/Lib/javascript/v8/javascriptcomplex.swg +++ b/Lib/javascript/v8/javascriptcomplex.swg @@ -17,7 +17,7 @@ SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) { SWIGV8_HANDLESCOPE_ESC(); - v8::Local vals = SWIGV8_ARRAY_NEW(); + v8::Local vals = SWIGV8_ARRAY_NEW(0); SWIGV8_ARRAY_SET(vals, 0, SWIG_From(double)(Real(c))); SWIGV8_ARRAY_SET(vals, 1, SWIG_From(double)(Imag(c))); @@ -39,23 +39,23 @@ SWIG_AsVal_dec(Type) (SWIGV8_VALUE o, Type* val) if (o->IsArray()) { SWIGV8_ARRAY array = SWIGV8_ARRAY::Cast(o); - if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); + if (array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); double re, im; int res; res = SWIG_AsVal(double)(SWIGV8_ARRAY_GET(array, 0), &re); - if(!SWIG_IsOK(res)) { + if (!SWIG_IsOK(res)) { return SWIG_TypeError; } res = SWIG_AsVal(double)(SWIGV8_ARRAY_GET(array, 1), &im); - if(!SWIG_IsOK(res)) { + if (!SWIG_IsOK(res)) { return SWIG_TypeError; } if (val) *val = Constructor(re, im); return SWIG_OK; - } else if(o->IsNumber()){ + } else if (o->IsNumber()) { double d; int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); if (SWIG_IsOK(res)) { @@ -81,17 +81,17 @@ SWIG_AsVal_dec(Type) (SWIGV8_VALUE o, Type* val) if (o->IsArray()) { SWIGV8_ARRAY array = SWIGV8_ARRAY::Cast(o); - if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); + if (array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); double re, im; int res; res = SWIG_AsVal(double)(SWIGV8_ARRAY_GET(array, 0), &re); - if(!SWIG_IsOK(res)) { + if (!SWIG_IsOK(res)) { return SWIG_TypeError; } res = SWIG_AsVal(double)(SWIGV8_ARRAY_GET(array, 1), &im); - if(!SWIG_IsOK(res)) { + if (!SWIG_IsOK(res)) { return SWIG_TypeError; } @@ -102,7 +102,7 @@ SWIG_AsVal_dec(Type) (SWIGV8_VALUE o, Type* val) } else { return SWIG_OverflowError; } - } else if(o->IsNumber()){ + } else if (o->IsNumber()) { float re; int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); if (SWIG_IsOK(res)) { diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg index bab259c03..642908a37 100644 --- a/Lib/javascript/v8/javascriptrun.swg +++ b/Lib/javascript/v8/javascriptrun.swg @@ -71,7 +71,7 @@ typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; #endif #if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318) -#define SWIGV8_ARRAY_NEW() v8::Array::New() +#define SWIGV8_ARRAY_NEW(size) v8::Array::New(size) #define SWIGV8_BOOLEAN_NEW(bool) v8::Boolean::New(bool) #define SWIGV8_EXTERNAL_NEW(val) v8::External::New(val) #define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(func) @@ -91,7 +91,7 @@ typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; #define SWIGV8_ARRAY_GET(array, index) (array)->Get(index) #define SWIGV8_ARRAY_SET(array, index, value) (array)->Set(index, value) #else -#define SWIGV8_ARRAY_NEW() v8::Array::New(v8::Isolate::GetCurrent()) +#define SWIGV8_ARRAY_NEW(size) v8::Array::New(v8::Isolate::GetCurrent(), size) #define SWIGV8_BOOLEAN_NEW(bool) v8::Boolean::New(v8::Isolate::GetCurrent(), bool) #define SWIGV8_EXTERNAL_NEW(val) v8::External::New(v8::Isolate::GetCurrent(), val) #define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(v8::Isolate::GetCurrent(), func) @@ -703,9 +703,9 @@ SWIGV8_VALUE SWIGV8_AppendOutput(SWIGV8_VALUE result, SWIGV8_VALUE obj) { SWIGV8_HANDLESCOPE_ESC(); if (result->IsUndefined()) { - result = SWIGV8_ARRAY_NEW(); + result = SWIGV8_ARRAY_NEW(0); } else if (!result->IsArray()) { - SWIGV8_ARRAY tmparr = SWIGV8_ARRAY_NEW(); + SWIGV8_ARRAY tmparr = SWIGV8_ARRAY_NEW(0); SWIGV8_ARRAY_SET(tmparr, 0, result); result = tmparr; }