Enable Wasm BigInt. This enables WASM_BIGINT while maintaining (hypothetical) Safari 14 support
by shimming BigInt64Array and BigUint64Array if they are missing. I think the
last time we tried to enable WASM_BIGINT was before #2019 so our chances
are significantly better this time.

This will fix dynamic linking bugs, reduce code size, and improve speed.

See also my upstream PR:
https://github.com/emscripten-core/emscripten/pull/17103

- [x] Add a [CHANGELOG](https://github.com/pyodide/pyodide/blob/main/docs/project/changelog.md) entry

From 1760850bf0f763b19ea5cd9de8f2e578bcc08a98 Mon Sep 17 00:00:00 2001
From: Hood Chatham <roberthoodchatham@gmail.com>
Date: Thu, 31 Mar 2022 17:24:13 -0700
Subject: [PATCH 10/14] make int return values

Make return values to fortran subroutines be consistently int.

This is because f2py defaults to making subroutines return void, whereas
f2c makes them int. On most systems this doesn't matter, but on WASM, strict
return type checking is used which makes things fail when f2py code calls
subroutines that were generated from fortran with f2c. To fix this we make
everything, including f2c, return int from subroutines.
---
 numpy/f2py/common_rules.py     |  6 +++---
 numpy/f2py/rules.py            |  6 +++---
 numpy/f2py/src/fortranobject.c |  7 +++++--
 numpy/f2py/src/fortranobject.h |  6 +++---
 numpy/linalg/lapack_lite/f2c.c | 11 ++++++-----
 numpy/linalg/lapack_lite/f2c.h | 10 +++++-----
 6 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/numpy/f2py/common_rules.py b/numpy/f2py/common_rules.py
index 937d8bc72..1bc01ecd1 100644
--- a/numpy/f2py/common_rules.py
+++ b/numpy/f2py/common_rules.py
@@ -104,7 +104,7 @@ def dadd(line, s=doc):
         cadd('\t{NULL}\n};')
         inames1 = rmbadname(inames)
         inames1_tps = ','.join(['char *' + s for s in inames1])
-        cadd('static void f2py_setup_%s(%s) {' % (name, inames1_tps))
+        cadd('static int f2py_setup_%s(%s) {' % (name, inames1_tps))
         cadd('\tint i_f2py=0;')
         for n in inames1:
             cadd('\tf2py_%s_def[i_f2py++].data = %s;' % (name, n))
@@ -113,10 +113,10 @@ def dadd(line, s=doc):
             F_FUNC = 'F_FUNC_US'
         else:
             F_FUNC = 'F_FUNC'
-        cadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void(*)(%s));'
+        cadd('extern int %s(f2pyinit%s,F2PYINIT%s)(int(*)(%s));'
              % (F_FUNC, lower_name, name.upper(),
                 ','.join(['char*'] * len(inames1))))
-        cadd('static void f2py_init_%s(void) {' % name)
+        cadd('static int f2py_init_%s(void) {' % name)
         cadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
              % (F_FUNC, lower_name, name.upper(), name))
         cadd('}\n')
diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py
index 78810a0a7..24cb06432 100755
--- a/numpy/f2py/rules.py
+++ b/numpy/f2py/rules.py
@@ -394,9 +394,9 @@
         'decl': '',
         '_check': ismoduleroutine
     }, {  # Subroutine
-        'functype': 'void',
-        'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
-                               l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern void #fortranname#(#callprotoargument#);',
+        'functype': 'int',
+        'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern int #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
+                               l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern int #fortranname#(#callprotoargument#);',
                                ismoduleroutine: '',
                                isdummyroutine: ''
                                },
diff --git a/numpy/f2py/src/fortranobject.c b/numpy/f2py/src/fortranobject.c
index c96378170..d7b9536d8 100644
--- a/numpy/f2py/src/fortranobject.c
+++ b/numpy/f2py/src/fortranobject.c
@@ -397,6 +397,10 @@ fortran_getattr(PyFortranObject *fp, char *name)
         return s;
     }
     if ((strcmp(name, "_cpointer") == 0) && (fp->len == 1)) {
+        if(fp->defs[0].data == NULL)
+        {
+            PyErr_Format(PyExc_AttributeError, "missing function pointer %s", fp->defs[0].name);
+        }
         PyObject *cobj =
                 F2PyCapsule_FromVoidPtr((void *)(fp->defs[0].data), NULL);
         if (PyDict_SetItemString(fp->dict, name, cobj))
@@ -483,8 +487,7 @@ fortran_setattr(PyFortranObject *fp, char *name, PyObject *v)
     if (v == NULL) {
         int rv = PyDict_DelItemString(fp->dict, name);
         if (rv < 0)
-            PyErr_SetString(PyExc_AttributeError,
-                            "delete non-existing fortran attribute");
+            PyErr_Format(PyExc_AttributeError,"delete non-existing fortran attribute %s",name);
         return rv;
     }
     else
diff --git a/numpy/f2py/src/fortranobject.h b/numpy/f2py/src/fortranobject.h
index a1e9fdbdf..a55335a8d 100644
--- a/numpy/f2py/src/fortranobject.h
+++ b/numpy/f2py/src/fortranobject.h
@@ -45,9 +45,9 @@ Author: Pearu Peterson <pearu@cens.ioc.ee>
 
 #define F2PY_MAX_DIMS 40
 
-typedef void (*f2py_set_data_func)(char *, npy_intp *);
-typedef void (*f2py_void_func)(void);
-typedef void (*f2py_init_func)(int *, npy_intp *, f2py_set_data_func, int *);
+typedef int (*f2py_set_data_func)(char*,npy_intp*);
+typedef int (*f2py_void_func)(void);
+typedef int (*f2py_init_func)(int*,npy_intp*,f2py_set_data_func,int*);
 
 /*typedef void* (*f2py_c_func)(void*,...);*/
 
diff --git a/numpy/linalg/lapack_lite/f2c.c b/numpy/linalg/lapack_lite/f2c.c
index 9a1e9cec1..f94cd5736 100644
--- a/numpy/linalg/lapack_lite/f2c.c
+++ b/numpy/linalg/lapack_lite/f2c.c
@@ -14,9 +14,9 @@
 #include "f2c.h"
 
 
-extern void s_wsfe(cilist *f) {;}
-extern void e_wsfe(void) {;}
-extern void do_fio(integer *c, char *s, ftnlen l) {;}
+extern int s_wsfe(cilist *f) {return 0;}
+extern int e_wsfe(void) {return 0;}
+extern int do_fio(integer *c, char *s, ftnlen l) {return 0;}
 
 /* You'll want this if you redo the f2c_*.c files with the -C option
  * to f2c for checking array subscripts. (It's not suggested you do that
@@ -377,7 +377,7 @@ p->i = p1.i;
 
 #endif /* NO_OVERWRITE */
 
- VOID
+ int
 #ifdef KR_headers
 s_cat(lp, rpp, rnp, np, ll) char *lp, *rpp[]; ftnlen rnp[], *np, ll;
 #else
@@ -487,7 +487,7 @@ return(0);
 #ifdef KR_headers
 VOID s_copy(a, b, la, lb) register char *a, *b; ftnlen la, lb;
 #else
-void s_copy(register char *a, register char *b, ftnlen la, ftnlen lb)
+int s_copy(register char *a, register char *b, ftnlen la, ftnlen lb)
 #endif
 {
 	register char *aend, *bend;
@@ -524,6 +524,7 @@ void s_copy(register char *a, register char *b, ftnlen la, ftnlen lb)
 		while(a < aend)
 			*a++ = ' ';
 		}
+        return 0;
 	}
 
 
diff --git a/numpy/linalg/lapack_lite/f2c.h b/numpy/linalg/lapack_lite/f2c.h
index d3fbfc177..b44aaac44 100644
--- a/numpy/linalg/lapack_lite/f2c.h
+++ b/numpy/linalg/lapack_lite/f2c.h
@@ -263,7 +263,7 @@ extern double d_tan(double *);
 extern double d_tanh(double *);
 extern double derf_(double *);
 extern double derfc_(double *);
-extern void do_fio(ftnint *, char *, ftnlen);
+extern int do_fio(ftnint *, char *, ftnlen);
 extern integer do_lio(ftnint *, ftnint *, char *, ftnlen);
 extern integer do_uio(ftnint *, char *, ftnlen);
 extern integer e_rdfe(void);
@@ -275,7 +275,7 @@ extern integer e_rsli(void);
 extern integer e_rsue(void);
 extern integer e_wdfe(void);
 extern integer e_wdue(void);
-extern void e_wsfe(void);
+extern int e_wsfe(void);
 extern integer e_wsfi(void);
 extern integer e_wsle(void);
 extern integer e_wsli(void);
@@ -350,9 +350,9 @@ extern double r_sinh(float *);
 extern double r_sqrt(float *);
 extern double r_tan(float *);
 extern double r_tanh(float *);
-extern void s_cat(char *, char **, integer *, integer *, ftnlen);
+extern int s_cat(char *, char **, integer *, integer *, ftnlen);
 extern integer s_cmp(char *, char *, ftnlen, ftnlen);
-extern void s_copy(char *, char *, ftnlen, ftnlen);
+extern int s_copy(char *, char *, ftnlen, ftnlen);
 extern int s_paus(char *, ftnlen);
 extern integer s_rdfe(cilist *);
 extern integer s_rdue(cilist *);
@@ -367,7 +367,7 @@ extern integer s_rsue(cilist *);
 extern int s_stop(char *, ftnlen);
 extern integer s_wdfe(cilist *);
 extern integer s_wdue(cilist *);
-extern void s_wsfe(	cilist *);
+extern int s_wsfe(	cilist *);
 extern integer s_wsfi(icilist *);
 extern integer s_wsle(cilist *);
 extern integer s_wsli(icilist *);
-- 
2.25.1


From 1760850bf0f763b19ea5cd9de8f2e578bcc08a98 Mon Sep 17 00:00:00 2001
From: Hood Chatham <roberthoodchatham@gmail.com>
Date: Thu, 31 Mar 2022 17:24:13 -0700
Subject: [PATCH 10/14] make int return values

Make return values to fortran subroutines be consistently int.

This is because f2py defaults to making subroutines return void, whereas
f2c makes them int. On most systems this doesn't matter, but on WASM, strict
return type checking is used which makes things fail when f2py code calls
subroutines that were generated from fortran with f2c. To fix this we make
everything, including f2c, return int from subroutines.
---
 numpy/f2py/common_rules.py     |  6 +++---
 numpy/f2py/rules.py            |  6 +++---
 numpy/f2py/src/fortranobject.c |  7 +++++--
 numpy/f2py/src/fortranobject.h |  6 +++---
 numpy/linalg/lapack_lite/f2c.c | 11 ++++++-----
 numpy/linalg/lapack_lite/f2c.h | 10 +++++-----
 6 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/numpy/f2py/common_rules.py b/numpy/f2py/common_rules.py
index 937d8bc72..1bc01ecd1 100644
--- a/numpy/f2py/common_rules.py
+++ b/numpy/f2py/common_rules.py
@@ -104,7 +104,7 @@ def dadd(line, s=doc):
         cadd('\t{NULL}\n};')
         inames1 = rmbadname(inames)
         inames1_tps = ','.join(['char *' + s for s in inames1])
-        cadd('static void f2py_setup_%s(%s) {' % (name, inames1_tps))
+        cadd('static int f2py_setup_%s(%s) {' % (name, inames1_tps))
         cadd('\tint i_f2py=0;')
         for n in inames1:
             cadd('\tf2py_%s_def[i_f2py++].data = %s;' % (name, n))
@@ -113,10 +113,10 @@ def dadd(line, s=doc):
             F_FUNC = 'F_FUNC_US'
         else:
             F_FUNC = 'F_FUNC'
-        cadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void(*)(%s));'
+        cadd('extern int %s(f2pyinit%s,F2PYINIT%s)(int(*)(%s));'
              % (F_FUNC, lower_name, name.upper(),
                 ','.join(['char*'] * len(inames1))))
-        cadd('static void f2py_init_%s(void) {' % name)
+        cadd('static int f2py_init_%s(void) {' % name)
         cadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
              % (F_FUNC, lower_name, name.upper(), name))
         cadd('}\n')
diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py
index 78810a0a7..24cb06432 100755
--- a/numpy/f2py/rules.py
+++ b/numpy/f2py/rules.py
@@ -394,9 +394,9 @@
         'decl': '',
         '_check': ismoduleroutine
     }, {  # Subroutine
-        'functype': 'void',
-        'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern void #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
-                               l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern void #fortranname#(#callprotoargument#);',
+        'functype': 'int',
+        'declfortranroutine': {l_and(l_not(l_or(ismoduleroutine, isintent_c)), l_not(isdummyroutine)): 'extern int #F_FUNC#(#fortranname#,#FORTRANNAME#)(#callprotoargument#);',
+                               l_and(l_not(ismoduleroutine), isintent_c, l_not(isdummyroutine)): 'extern int #fortranname#(#callprotoargument#);',
                                ismoduleroutine: '',
                                isdummyroutine: ''
                                },
diff --git a/numpy/f2py/src/fortranobject.c b/numpy/f2py/src/fortranobject.c
index c96378170..d7b9536d8 100644
--- a/numpy/f2py/src/fortranobject.c
+++ b/numpy/f2py/src/fortranobject.c
@@ -397,6 +397,10 @@ fortran_getattr(PyFortranObject *fp, char *name)
         return s;
     }
     if ((strcmp(name, "_cpointer") == 0) && (fp->len == 1)) {
+        if(fp->defs[0].data == NULL)
+        {
+            PyErr_Format(PyExc_AttributeError, "missing function pointer %s", fp->defs[0].name);
+        }
         PyObject *cobj =
                 F2PyCapsule_FromVoidPtr((void *)(fp->defs[0].data), NULL);
         if (PyDict_SetItemString(fp->dict, name, cobj))
@@ -483,8 +487,7 @@ fortran_setattr(PyFortranObject *fp, char *name, PyObject *v)
     if (v == NULL) {
         int rv = PyDict_DelItemString(fp->dict, name);
         if (rv < 0)
-            PyErr_SetString(PyExc_AttributeError,
-                            "delete non-existing fortran attribute");
+            PyErr_Format(PyExc_AttributeError,"delete non-existing fortran attribute %s",name);
         return rv;
     }
     else
diff --git a/numpy/f2py/src/fortranobject.h b/numpy/f2py/src/fortranobject.h
index a1e9fdbdf..a55335a8d 100644
--- a/numpy/f2py/src/fortranobject.h
+++ b/numpy/f2py/src/fortranobject.h
@@ -45,9 +45,9 @@ Author: Pearu Peterson <pearu@cens.ioc.ee>
 
 #define F2PY_MAX_DIMS 40
 
-typedef void (*f2py_set_data_func)(char *, npy_intp *);
-typedef void (*f2py_void_func)(void);
-typedef void (*f2py_init_func)(int *, npy_intp *, f2py_set_data_func, int *);
+typedef int (*f2py_set_data_func)(char*,npy_intp*);
+typedef int (*f2py_void_func)(void);
+typedef int (*f2py_init_func)(int*,npy_intp*,f2py_set_data_func,int*);
 
 /*typedef void* (*f2py_c_func)(void*,...);*/
 
diff --git a/numpy/linalg/lapack_lite/f2c.c b/numpy/linalg/lapack_lite/f2c.c
index 9a1e9cec1..f94cd5736 100644
--- a/numpy/linalg/lapack_lite/f2c.c
+++ b/numpy/linalg/lapack_lite/f2c.c
@@ -14,9 +14,9 @@
 #include "f2c.h"
 
 
-extern void s_wsfe(cilist *f) {;}
-extern void e_wsfe(void) {;}
-extern void do_fio(integer *c, char *s, ftnlen l) {;}
+extern int s_wsfe(cilist *f) {return 0;}
+extern int e_wsfe(void) {return 0;}
+extern int do_fio(integer *c, char *s, ftnlen l) {return 0;}
 
 /* You'll want this if you redo the f2c_*.c files with the -C option
  * to f2c for checking array subscripts. (It's not suggested you do that
@@ -377,7 +377,7 @@ p->i = p1.i;
 
 #endif /* NO_OVERWRITE */
 
- VOID
+ int
 #ifdef KR_headers
 s_cat(lp, rpp, rnp, np, ll) char *lp, *rpp[]; ftnlen rnp[], *np, ll;
 #else
@@ -487,7 +487,7 @@ return(0);
 #ifdef KR_headers
 VOID s_copy(a, b, la, lb) register char *a, *b; ftnlen la, lb;
 #else
-void s_copy(register char *a, register char *b, ftnlen la, ftnlen lb)
+int s_copy(register char *a, register char *b, ftnlen la, ftnlen lb)
 #endif
 {
 	register char *aend, *bend;
@@ -524,6 +524,7 @@ void s_copy(register char *a, register char *b, ftnlen la, ftnlen lb)
 		while(a < aend)
 			*a++ = ' ';
 		}
+        return 0;
 	}
 
 
diff --git a/numpy/linalg/lapack_lite/f2c.h b/numpy/linalg/lapack_lite/f2c.h
index d3fbfc177..b44aaac44 100644
--- a/numpy/linalg/lapack_lite/f2c.h
+++ b/numpy/linalg/lapack_lite/f2c.h
@@ -263,7 +263,7 @@ extern double d_tan(double *);
 extern double d_tanh(double *);
 extern double derf_(double *);
 extern double derfc_(double *);
-extern void do_fio(ftnint *, char *, ftnlen);
+extern int do_fio(ftnint *, char *, ftnlen);
 extern integer do_lio(ftnint *, ftnint *, char *, ftnlen);
 extern integer do_uio(ftnint *, char *, ftnlen);
 extern integer e_rdfe(void);
@@ -275,7 +275,7 @@ extern integer e_rsli(void);
 extern integer e_rsue(void);
 extern integer e_wdfe(void);
 extern integer e_wdue(void);
-extern void e_wsfe(void);
+extern int e_wsfe(void);
 extern integer e_wsfi(void);
 extern integer e_wsle(void);
 extern integer e_wsli(void);
@@ -350,9 +350,9 @@ extern double r_sinh(float *);
 extern double r_sqrt(float *);
 extern double r_tan(float *);
 extern double r_tanh(float *);
-extern void s_cat(char *, char **, integer *, integer *, ftnlen);
+extern int s_cat(char *, char **, integer *, integer *, ftnlen);
 extern integer s_cmp(char *, char *, ftnlen, ftnlen);
-extern void s_copy(char *, char *, ftnlen, ftnlen);
+extern int s_copy(char *, char *, ftnlen, ftnlen);
 extern int s_paus(char *, ftnlen);
 extern integer s_rdfe(cilist *);
 extern integer s_rdue(cilist *);
@@ -367,7 +367,7 @@ extern integer s_rsue(cilist *);
 extern int s_stop(char *, ftnlen);
 extern integer s_wdfe(cilist *);
 extern integer s_wdue(cilist *);
-extern void s_wsfe(	cilist *);
+extern int s_wsfe(	cilist *);
 extern integer s_wsfi(icilist *);
 extern integer s_wsle(cilist *);
 extern integer s_wsli(icilist *);
-- 
2.25.1

