mirror of
https://github.com/libffi/libffi.git
synced 2026-01-26 18:08:57 +00:00
Emscripten: remove support for -sWASM_BIGINT=0 (#874)
* Emscripten: cleanup * Emscripten: remove support for `-sWASM_BIGINT=0` * Emscripten: remove redundant CircleCI config * Emscripten: modernize CI * Ensure test helper methods are static Similar to #644. * Fix test failures in `cls_multi_{s,u}shortchar`
This commit is contained in:
parent
2f34cf639c
commit
adfe4489c1
@ -1,156 +0,0 @@
|
||||
version: 2.1
|
||||
|
||||
defaults: &defaults
|
||||
working_directory: ~/repo
|
||||
docker:
|
||||
# Built from:
|
||||
# https://github.com/pyodide/pyodide/blob/2ab4b0ab6aefe99fd994bb4f9ab086e5c0aebb7b/Dockerfile
|
||||
- image: pyodide/pyodide-env:20230126-chrome109-firefox109-py311
|
||||
|
||||
jobs:
|
||||
install-emsdk:
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: install emsdk
|
||||
command: |
|
||||
git clone https://github.com/emscripten-core/emsdk.git --depth=1
|
||||
cd emsdk
|
||||
./emsdk install 3.1.30
|
||||
./emsdk activate 3.1.30
|
||||
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- emsdk
|
||||
|
||||
build:
|
||||
parameters:
|
||||
wasm-bigint:
|
||||
description: Should we build with wasm-bigint?
|
||||
type: string
|
||||
default: ""
|
||||
environment:
|
||||
WASM_BIGINT: << parameters.wasm-bigint >>
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
|
||||
- run:
|
||||
name: build
|
||||
command: |
|
||||
source ./emsdk/emsdk_env.sh
|
||||
./testsuite/emscripten/build.sh
|
||||
|
||||
- run:
|
||||
name: build tests
|
||||
command: |
|
||||
source ./emsdk/emsdk_env.sh
|
||||
cp -r testsuite/libffi.call testsuite/libffi.call.test
|
||||
cp -r testsuite/libffi.closures testsuite/libffi.closures.test
|
||||
./testsuite/emscripten/build-tests.sh testsuite/libffi.call.test
|
||||
./testsuite/emscripten/build-tests.sh testsuite/libffi.closures.test
|
||||
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- target
|
||||
- testsuite
|
||||
|
||||
test:
|
||||
parameters:
|
||||
test-params:
|
||||
description: The tests to run.
|
||||
type: string
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
- attach_workspace:
|
||||
at: .
|
||||
|
||||
- run:
|
||||
name: run tests
|
||||
command: |
|
||||
git reset --hard
|
||||
cd testsuite/emscripten/
|
||||
mkdir test-results
|
||||
pytest \
|
||||
--junitxml=test-results/junit.xml \
|
||||
test_libffi.py \
|
||||
<< parameters.test-params >>
|
||||
- store_test_results:
|
||||
path: testsuite/emscripten/test-results
|
||||
|
||||
test-dejagnu:
|
||||
parameters:
|
||||
params:
|
||||
description: Parameters to node-tests
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
<<: *defaults
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
- attach_workspace:
|
||||
at: .
|
||||
|
||||
- run:
|
||||
name: run tests
|
||||
command: |
|
||||
source ./emsdk/emsdk_env.sh
|
||||
testsuite/emscripten/node-tests.sh << parameters.params >>
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build-and-test:
|
||||
jobs:
|
||||
- install-emsdk
|
||||
|
||||
- build:
|
||||
name: build
|
||||
requires:
|
||||
- install-emsdk
|
||||
|
||||
- build:
|
||||
name: build-bigint
|
||||
wasm-bigint: "true"
|
||||
requires:
|
||||
- install-emsdk
|
||||
|
||||
- test:
|
||||
name: test-firefox
|
||||
test-params: -k firefox
|
||||
requires:
|
||||
- build
|
||||
- test:
|
||||
name: test-chrome
|
||||
test-params: -k chrome
|
||||
requires:
|
||||
- build
|
||||
|
||||
- test:
|
||||
name: test-firefox-bigint
|
||||
test-params: -k firefox
|
||||
requires:
|
||||
- build-bigint
|
||||
|
||||
- test:
|
||||
name: test-chrome-bigint
|
||||
test-params: -k chrome
|
||||
requires:
|
||||
- build-bigint
|
||||
|
||||
- test-dejagnu:
|
||||
name: test-dejagnu
|
||||
requires:
|
||||
- install-emsdk
|
||||
- test-dejagnu:
|
||||
name: test-dejagnu-bigint
|
||||
params: --wasm-bigint
|
||||
requires:
|
||||
- install-emsdk
|
||||
110
.github/workflows/emscripten.yml
vendored
110
.github/workflows/emscripten.yml
vendored
@ -13,13 +13,13 @@ on:
|
||||
|
||||
|
||||
env:
|
||||
PYODIDE_VERSION: 0.52.1
|
||||
PYODIDE_VERSION: 0.58.4
|
||||
# PYTHON_VERSION and EMSCRIPTEN_VERSION are determined by PYODIDE_VERSION.
|
||||
# The appropriate versions can be found in the Pyodide repodata.json
|
||||
# "info" field, or in Makefile.envs:
|
||||
# https://github.com/pyodide/pyodide/blob/main/Makefile.envs#L2
|
||||
PYTHON_VERSION: 3.10.7
|
||||
EMSCRIPTEN_VERSION: 3.1.27
|
||||
PYTHON_VERSION: 3.12.7
|
||||
EMSCRIPTEN_VERSION: 3.1.58
|
||||
EM_CACHE_FOLDER: emsdk-cache
|
||||
|
||||
jobs:
|
||||
@ -27,53 +27,46 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Setup cache
|
||||
id: cache-system-libraries
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.EM_CACHE_FOLDER}}
|
||||
key: ${{env.EMSCRIPTEN_VERSION}}
|
||||
path: ${{ env.EM_CACHE_FOLDER }}
|
||||
key: ${{ env.EMSCRIPTEN_VERSION }}
|
||||
|
||||
- uses: mymindstorm/setup-emsdk@v12
|
||||
- name: Setup emsdk
|
||||
uses: mymindstorm/setup-emsdk@v14
|
||||
with:
|
||||
version: ${{ env.EMSCRIPTEN_VERSION }}
|
||||
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
||||
actions-cache-folder: ${{ env.EM_CACHE_FOLDER }}
|
||||
|
||||
test-dejagnu:
|
||||
strategy:
|
||||
matrix:
|
||||
bigint: ["--wasm-bigint", ""]
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [setup-emsdk-cache]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: set up python
|
||||
id: setup-python
|
||||
uses: actions/setup-python@v4
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
|
||||
- name: Setup cache
|
||||
id: cache-system-libraries
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.EM_CACHE_FOLDER}}
|
||||
key: ${{env.EMSCRIPTEN_VERSION}}
|
||||
path: ${{ env.EM_CACHE_FOLDER }}
|
||||
key: ${{ env.EMSCRIPTEN_VERSION }}
|
||||
|
||||
- uses: mymindstorm/setup-emsdk@v12
|
||||
- name: Setup emsdk
|
||||
uses: mymindstorm/setup-emsdk@v14
|
||||
with:
|
||||
version: ${{ env.EMSCRIPTEN_VERSION }}
|
||||
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
||||
actions-cache-folder: ${{ env.EM_CACHE_FOLDER }}
|
||||
|
||||
- name: Install dejagnu
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
sudo apt install -y dejagnu
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install dejagnu libltdl-dev
|
||||
|
||||
- name: run tests
|
||||
run: |
|
||||
testsuite/emscripten/node-tests.sh ${{ matrix.bigint }}
|
||||
- name: Run tests
|
||||
run: testsuite/emscripten/node-tests.sh
|
||||
|
||||
- name: Install rlgl and run
|
||||
run: |
|
||||
@ -84,75 +77,70 @@ jobs:
|
||||
exit $?
|
||||
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
bigint: ["--wasm-bigint", ""]
|
||||
env:
|
||||
WASM_BIGINT: ${{ matrix.bigint }}
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [setup-emsdk-cache]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup cache
|
||||
id: cache-system-libraries
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.EM_CACHE_FOLDER}}
|
||||
key: ${{env.EMSCRIPTEN_VERSION}}
|
||||
path: ${{ env.EM_CACHE_FOLDER }}
|
||||
key: ${{ env.EMSCRIPTEN_VERSION }}
|
||||
|
||||
- uses: mymindstorm/setup-emsdk@v12
|
||||
- name: Setup emsdk
|
||||
uses: mymindstorm/setup-emsdk@v12
|
||||
with:
|
||||
version: ${{ env.EMSCRIPTEN_VERSION }}
|
||||
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
||||
actions-cache-folder: ${{ env.EM_CACHE_FOLDER }}
|
||||
|
||||
- name: build
|
||||
run: |
|
||||
./testsuite/emscripten/build.sh ${{ matrix.bigint }}
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install libltdl-dev
|
||||
|
||||
- name: build tests
|
||||
- name: Build
|
||||
run: ./testsuite/emscripten/build.sh
|
||||
|
||||
- name: Build tests
|
||||
run: |
|
||||
cp -r testsuite/libffi.call testsuite/libffi.call.test
|
||||
cp -r testsuite/libffi.closures testsuite/libffi.closures.test
|
||||
./testsuite/emscripten/build-tests.sh testsuite/libffi.call.test ${{ matrix.bigint }}
|
||||
./testsuite/emscripten/build-tests.sh testsuite/libffi.closures.test ${{ matrix.bigint }}
|
||||
./testsuite/emscripten/build-tests.sh testsuite/libffi.call.test
|
||||
./testsuite/emscripten/build-tests.sh testsuite/libffi.closures.test
|
||||
|
||||
- name: Store artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: built-tests
|
||||
path: |
|
||||
./testsuite/libffi.c*/
|
||||
path: ./testsuite/libffi.c*/
|
||||
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
bigint: ["--wasm-bigint", ""]
|
||||
browser: ["chrome"]
|
||||
# FIXME: selenium can't find gecko driver for "firefox"
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [build]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download build artifact
|
||||
uses: actions/download-artifact@v4.1.7
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: built-tests
|
||||
path: ./testsuite/
|
||||
|
||||
- uses: conda-incubator/setup-miniconda@v2
|
||||
- uses: conda-incubator/setup-miniconda@v3
|
||||
with:
|
||||
activate-environment: pyodide-env
|
||||
python-version: ${{ env.PYTHON_VERSION }}
|
||||
channels: conda-forge
|
||||
- name: Install test dependencies
|
||||
run: |
|
||||
pip install pytest-pyodide==${{ env.PYODIDE_VERSION }}
|
||||
|
||||
- name:
|
||||
- name: Install test dependencies
|
||||
run: pip install pytest-pyodide==${{ env.PYODIDE_VERSION }}
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd testsuite/emscripten/
|
||||
mkdir test-results
|
||||
|
||||
272
src/wasm32/ffi.c
272
src/wasm32/ffi.c
@ -41,28 +41,7 @@
|
||||
|
||||
#define EM_JS_MACROS(ret, name, args, body...) EM_JS(ret, name, args, body)
|
||||
|
||||
#if WASM_BIGINT
|
||||
EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$convertJsFunctionToWasm");
|
||||
#define CALL_FUNCTION_POINTER(ptr, args...) \
|
||||
(LOG_DEBUG("CALL_FUNC_PTR", ptr, args), \
|
||||
getWasmTableEntry(ptr).apply(null, args))
|
||||
|
||||
#define JS_FUNCTION_TO_WASM convertJsFunctionToWasm
|
||||
#else
|
||||
EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$convertJsFunctionToWasm,$dynCall,$generateFuncType,$uleb128Encode");
|
||||
#define CALL_FUNCTION_POINTER(ptr, args...) \
|
||||
(LOG_DEBUG("CALL_FUNC_PTR", sig, ptr, args), \
|
||||
dynCall(sig, ptr, args))
|
||||
|
||||
#define JS_FUNCTION_TO_WASM createLegalizerWrapper
|
||||
#endif
|
||||
|
||||
// Signature calculations are not needed if WASM_BIGINT is present.
|
||||
#if WASM_BIGINT
|
||||
#define SIG(sig)
|
||||
#else
|
||||
#define SIG(sig) sig
|
||||
#endif
|
||||
|
||||
#define DEREF_U8(addr, offset) HEAPU8[addr + offset]
|
||||
#define DEREF_S8(addr, offset) HEAP8[addr + offset]
|
||||
@ -73,12 +52,7 @@ EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$co
|
||||
|
||||
#define DEREF_F32(addr, offset) HEAPF32[(addr >> 2) + offset]
|
||||
#define DEREF_F64(addr, offset) HEAPF64[(addr >> 3) + offset]
|
||||
|
||||
#if WASM_BIGINT
|
||||
// We have HEAPU64 in this case.
|
||||
#define DEREF_U64(addr, offset) HEAPU64[(addr >> 3) + offset]
|
||||
#endif
|
||||
|
||||
|
||||
#define CHECK_FIELD_OFFSET(struct, field, offset) \
|
||||
_Static_assert( \
|
||||
@ -235,40 +209,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
||||
ret_by_arg = true;
|
||||
}
|
||||
|
||||
SIG(var sig = "");
|
||||
|
||||
#if !WASM_BIGINT
|
||||
switch(rtype_id) {
|
||||
case FFI_TYPE_VOID:
|
||||
SIG(sig = 'v');
|
||||
break;
|
||||
case FFI_TYPE_STRUCT:
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
SIG(sig = 'vi');
|
||||
break;
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
SIG(sig = 'i');
|
||||
break;
|
||||
case FFI_TYPE_FLOAT:
|
||||
SIG(sig = 'f');
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
SIG(sig = 'd');
|
||||
break;
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
SIG(sig = 'j');
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Accumulate a Javascript list of arguments for the Javascript wrapper for
|
||||
// the wasm function. The Javascript wrapper does a type conversion from
|
||||
// Javascript to C automatically, here we manually do the inverse conversion
|
||||
@ -288,54 +228,33 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
args.push(DEREF_U32(arg_ptr, 0));
|
||||
SIG(sig += 'i');
|
||||
break;
|
||||
case FFI_TYPE_FLOAT:
|
||||
args.push(DEREF_F32(arg_ptr, 0));
|
||||
SIG(sig += 'f');
|
||||
break;
|
||||
case FFI_TYPE_DOUBLE:
|
||||
args.push(DEREF_F64(arg_ptr, 0));
|
||||
SIG(sig += 'd');
|
||||
break;
|
||||
case FFI_TYPE_UINT8:
|
||||
args.push(DEREF_U8(arg_ptr, 0));
|
||||
SIG(sig += 'i');
|
||||
break;
|
||||
case FFI_TYPE_SINT8:
|
||||
args.push(DEREF_S8(arg_ptr, 0));
|
||||
SIG(sig += 'i');
|
||||
break;
|
||||
case FFI_TYPE_UINT16:
|
||||
args.push(DEREF_U16(arg_ptr, 0));
|
||||
SIG(sig += 'i');
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
args.push(DEREF_S16(arg_ptr, 0));
|
||||
SIG(sig += 'i');
|
||||
break;
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
#if WASM_BIGINT
|
||||
args.push(DEREF_U64(arg_ptr, 0));
|
||||
#else
|
||||
args.push(DEREF_U32(arg_ptr, 0));
|
||||
args.push(DEREF_U32(arg_ptr, 1));
|
||||
#endif
|
||||
SIG(sig += 'j');
|
||||
break;
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
// long double is passed as a pair of BigInts.
|
||||
#if WASM_BIGINT
|
||||
args.push(DEREF_U64(arg_ptr, 0));
|
||||
args.push(DEREF_U64(arg_ptr, 1));
|
||||
#else
|
||||
args.push(DEREF_U32(arg_ptr, 0));
|
||||
args.push(DEREF_U32(arg_ptr, 1));
|
||||
args.push(DEREF_U32(arg_ptr, 2));
|
||||
args.push(DEREF_U32(arg_ptr, 3));
|
||||
#endif
|
||||
SIG(sig += "jj");
|
||||
break;
|
||||
case FFI_TYPE_STRUCT:
|
||||
// Nontrivial structs are passed by pointer.
|
||||
@ -346,7 +265,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
||||
STACK_ALLOC(cur_stack_ptr, size, align);
|
||||
HEAP8.subarray(cur_stack_ptr, cur_stack_ptr+size).set(HEAP8.subarray(arg_ptr, arg_ptr + size));
|
||||
args.push(cur_stack_ptr);
|
||||
SIG(sig += 'i');
|
||||
break;
|
||||
case FFI_TYPE_COMPLEX:
|
||||
throw new Error('complex marshalling nyi');
|
||||
@ -365,7 +283,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
||||
// just always copy extra nonsense past the end. The ownwards call will know
|
||||
// not to look at it.
|
||||
if (nfixedargs != nargs) {
|
||||
SIG(sig += 'i');
|
||||
var struct_arg_info = [];
|
||||
for (var i = nargs - 1; i >= nfixedargs; i--) {
|
||||
var arg_ptr = DEREF_U32(avalue, i);
|
||||
@ -434,7 +351,8 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
||||
}
|
||||
stackRestore(cur_stack_ptr);
|
||||
stackAlloc(0); // stackAlloc enforces alignment invariants on the stack pointer
|
||||
var result = CALL_FUNCTION_POINTER(fn, args);
|
||||
LOG_DEBUG("CALL_FUNC_PTR", "fn:", fn, "args:", args);
|
||||
var result = getWasmTableEntry(fn).apply(null, args);
|
||||
// Put the stack pointer back (we moved it if there were any struct args or we
|
||||
// made a varargs call)
|
||||
stackRestore(orig_stack_ptr);
|
||||
@ -472,12 +390,7 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
||||
break;
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_SINT64:
|
||||
#if WASM_BIGINT
|
||||
DEREF_U64(rvalue, 0) = result;
|
||||
#else
|
||||
DEREF_U32(rvalue, 0) = result;
|
||||
DEREF_U32(rvalue, 1) = getTempRet0();
|
||||
#endif
|
||||
break;
|
||||
case FFI_TYPE_COMPLEX:
|
||||
throw new Error('complex ret marshalling nyi');
|
||||
@ -524,146 +437,6 @@ ffi_closure_free(void *closure) {
|
||||
return ffi_closure_free_js(closure);
|
||||
}
|
||||
|
||||
#if !WASM_BIGINT
|
||||
|
||||
// When !WASM_BIGINT, we assume there is no JS bigint integration, so JavaScript
|
||||
// functions cannot take 64 bit integer arguments.
|
||||
//
|
||||
// We need to make our own wasm legalizer adaptor that splits 64 bit integer
|
||||
// arguments and then calls the JavaScript trampoline, then the JavaScript
|
||||
// trampoline reassembles them, calls the closure, then splits the result (if
|
||||
// it's a 64 bit integer) and the adaptor puts it back together.
|
||||
//
|
||||
// This is basically the reverse of the Emscripten function
|
||||
// createDyncallWrapper.
|
||||
EM_JS(void, createLegalizerWrapper, (int trampoline, int sig), {
|
||||
if(!sig.includes("j")) {
|
||||
return convertJsFunctionToWasm(trampoline, sig);
|
||||
}
|
||||
var sections = [];
|
||||
var prelude = [
|
||||
0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
|
||||
0x01, 0x00, 0x00, 0x00, // version: 1
|
||||
];
|
||||
sections.push(prelude);
|
||||
var wrappersig = [
|
||||
// if return type is j, we will put the upper 32 bits into tempRet0.
|
||||
sig[0].replace("j", "i"),
|
||||
// in the rest of the argument list, one 64 bit integer is legalized into
|
||||
// two 32 bit integers.
|
||||
sig.slice(1).replace(/j/g, "ii"),
|
||||
].join("");
|
||||
|
||||
var typeSectionBody = [
|
||||
0x03, // number of types = 3
|
||||
];
|
||||
generateFuncType(wrappersig, typeSectionBody); // The signature of the wrapper we are generating
|
||||
generateFuncType(sig, typeSectionBody); // the signature of the function pointer we will call
|
||||
generateFuncType("i", typeSectionBody); // the signature of getTempRet0
|
||||
|
||||
var typeSection = [0x01 /* Type section code */];
|
||||
uleb128Encode(typeSectionBody.length, typeSection); // length of section in bytes
|
||||
typeSection.push.apply(typeSection, typeSectionBody);
|
||||
sections.push(typeSection);
|
||||
|
||||
var importSection = [
|
||||
0x02, // import section code
|
||||
0x0d, // length of section in bytes
|
||||
0x02, // number of imports = 2
|
||||
// Import the getTempRet0 function, which we will call "r"
|
||||
0x01, 0x65, // name "e"
|
||||
0x01, 0x72, // name "r"
|
||||
0x00, // importing a function
|
||||
0x02, // type 2 = () -> i32
|
||||
// Import the wrapped function, which we will call "f"
|
||||
0x01, 0x65, // name "e"
|
||||
0x01, 0x66, // name "f"
|
||||
0x00, // importing a function
|
||||
0x00, // type 0 = wrappersig
|
||||
];
|
||||
sections.push(importSection);
|
||||
|
||||
var functionSection = [
|
||||
0x03, // function section code
|
||||
0x02, // length of section in bytes
|
||||
0x01, // number of functions = 1
|
||||
0x01, // type 1 = sig
|
||||
];
|
||||
sections.push(functionSection);
|
||||
|
||||
var exportSection = [
|
||||
0x07, // export section code
|
||||
0x05, // length of section in bytes
|
||||
0x01, // One export
|
||||
0x01, 0x66, // name "f"
|
||||
0x00, // type: function
|
||||
0x02, // function index 2 = the wrapper function
|
||||
];
|
||||
sections.push(exportSection);
|
||||
|
||||
var convert_code = [];
|
||||
convert_code.push(0x00); // no local variables (except the arguments)
|
||||
|
||||
function localGet(j) {
|
||||
convert_code.push(0x20); // local.get
|
||||
uleb128Encode(j, convert_code);
|
||||
}
|
||||
|
||||
for (var i = 1; i < sig.length; i++) {
|
||||
if (sig[i] == "j") {
|
||||
localGet(i - 1);
|
||||
convert_code.push(
|
||||
0xa7 // i32.wrap_i64
|
||||
);
|
||||
localGet(i - 1);
|
||||
convert_code.push(
|
||||
0x42, 0x20, // i64.const 32
|
||||
0x88, // i64.shr_u
|
||||
0xa7 // i32.wrap_i64
|
||||
);
|
||||
} else {
|
||||
localGet(i - 1);
|
||||
}
|
||||
}
|
||||
convert_code.push(
|
||||
0x10, 0x01 // call f
|
||||
);
|
||||
if (sig[0] === "j") {
|
||||
// Need to reassemble a 64 bit integer. Lower 32 bits is on stack. Upper 32
|
||||
// bits we get from getTempRet0
|
||||
convert_code.push(
|
||||
0xad, // i64.extend_i32_unsigned
|
||||
0x10, 0x00, // Call function 0 (r = getTempRet0)
|
||||
// join lower 32 bits and upper 32 bits
|
||||
0xac, // i64.extend_i32_signed
|
||||
0x42, 0x20, // i64.const 32
|
||||
0x86, // i64.shl,
|
||||
0x84 // i64.or
|
||||
);
|
||||
}
|
||||
convert_code.push(0x0b); // end
|
||||
|
||||
var codeBody = [0x01]; // one code
|
||||
uleb128Encode(convert_code.length, codeBody);
|
||||
codeBody.push.apply(codeBody, convert_code);
|
||||
var codeSection = [0x0a /* Code section code */];
|
||||
uleb128Encode(codeBody.length, codeSection);
|
||||
codeSection.push.apply(codeSection, codeBody);
|
||||
sections.push(codeSection);
|
||||
|
||||
var bytes = new Uint8Array([].concat.apply([], sections));
|
||||
// We can compile this wasm module synchronously because it is small.
|
||||
var module = new WebAssembly.Module(bytes);
|
||||
var instance = new WebAssembly.Instance(module, {
|
||||
e: {
|
||||
r: getTempRet0,
|
||||
f: trampoline,
|
||||
},
|
||||
});
|
||||
return instance.exports.f;
|
||||
});
|
||||
#endif
|
||||
|
||||
EM_JS_MACROS(
|
||||
ffi_status,
|
||||
ffi_prep_closure_loc_js,
|
||||
@ -759,9 +532,9 @@ ffi_prep_closure_loc_js,
|
||||
}
|
||||
if (nfixedargs < nargs) {
|
||||
// extra pointer to varargs stack
|
||||
sig += "i";
|
||||
sig += 'i';
|
||||
}
|
||||
LOG_DEBUG("CREATE_CLOSURE", "sig:", sig);
|
||||
LOG_DEBUG("CREATE_CLOSURE", "sig:", sig);
|
||||
function trampoline() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var size = 0;
|
||||
@ -838,32 +611,14 @@ ffi_prep_closure_loc_js,
|
||||
case FFI_TYPE_SINT64:
|
||||
STACK_ALLOC(cur_ptr, 8, 8);
|
||||
DEREF_U32(args_ptr, carg_idx) = cur_ptr;
|
||||
#if WASM_BIGINT
|
||||
DEREF_U64(cur_ptr, 0) = cur_arg;
|
||||
#else
|
||||
// Bigint arg was split by legalizer adaptor
|
||||
DEREF_U32(cur_ptr, 0) = cur_arg;
|
||||
cur_arg = args[jsarg_idx++];
|
||||
DEREF_U32(cur_ptr, 1) = cur_arg;
|
||||
#endif
|
||||
break;
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
STACK_ALLOC(cur_ptr, 16, 8);
|
||||
DEREF_U32(args_ptr, carg_idx) = cur_ptr;
|
||||
#if WASM_BIGINT
|
||||
DEREF_U64(cur_ptr, 0) = cur_arg;
|
||||
cur_arg = args[jsarg_idx++];
|
||||
DEREF_U64(cur_ptr, 1) = cur_arg;
|
||||
#else
|
||||
// Was split by legalizer adaptor
|
||||
DEREF_U32(cur_ptr, 0) = cur_arg;
|
||||
cur_arg = args[jsarg_idx++];
|
||||
DEREF_U32(cur_ptr, 1) = cur_arg;
|
||||
cur_arg = args[jsarg_idx++];
|
||||
DEREF_U32(cur_ptr, 2) = cur_arg;
|
||||
cur_arg = args[jsarg_idx++];
|
||||
DEREF_U32(cur_ptr, 3) = cur_arg;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -895,7 +650,7 @@ ffi_prep_closure_loc_js,
|
||||
}
|
||||
stackRestore(cur_ptr);
|
||||
stackAlloc(0); // stackAlloc enforces alignment invariants on the stack pointer
|
||||
LOG_DEBUG("CALL_CLOSURE", "closure:", closure, "fptr", CLOSURE__fun(closure), "cif", CLOSURE__cif(closure));
|
||||
LOG_DEBUG("CALL_CLOSURE", "closure:", closure, "fptr", CLOSURE__fun(closure), "cif", CLOSURE__cif(closure));
|
||||
getWasmTableEntry(CLOSURE__fun(closure))(
|
||||
CLOSURE__cif(closure), ret_ptr, args_ptr,
|
||||
CLOSURE__user_data(closure)
|
||||
@ -905,26 +660,19 @@ ffi_prep_closure_loc_js,
|
||||
// If we aren't supposed to return by argument, figure out what to return.
|
||||
if (!ret_by_arg) {
|
||||
switch (sig[0]) {
|
||||
case "i":
|
||||
case 'i':
|
||||
return DEREF_U32(ret_ptr, 0);
|
||||
case "j":
|
||||
#if WASM_BIGINT
|
||||
case 'j':
|
||||
return DEREF_U64(ret_ptr, 0);
|
||||
#else
|
||||
// Split the return i64, set the upper 32 bits into tempRet0 and return
|
||||
// the lower 32 bits.
|
||||
setTempRet0(DEREF_U32(ret_ptr, 1));
|
||||
return DEREF_U32(ret_ptr, 0);
|
||||
#endif
|
||||
case "d":
|
||||
case 'd':
|
||||
return DEREF_F64(ret_ptr, 0);
|
||||
case "f":
|
||||
case 'f':
|
||||
return DEREF_F32(ret_ptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
var wasm_trampoline = JS_FUNCTION_TO_WASM(trampoline, sig);
|
||||
var wasm_trampoline = convertJsFunctionToWasm(trampoline, sig);
|
||||
} catch(e) {
|
||||
return FFI_BAD_TYPEDEF_MACRO;
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
emcc_exists="$(command -v emcc)"
|
||||
if [ ! "${emcc_exists}" ]; then
|
||||
echo "Emscripten not on path"
|
||||
|
||||
if ! [ -x "$(command -v emcc)" ]; then
|
||||
echo "Error: emcc could not be found." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -10,19 +10,6 @@ set -e
|
||||
cd "$1"
|
||||
shift
|
||||
|
||||
# Parse arguments
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--wasm-bigint) WASM_BIGINT=true ;;
|
||||
*)
|
||||
echo "ERROR: Unknown parameter: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
export CFLAGS="-fPIC -O2 -I../../target/include $EXTRA_CFLAGS"
|
||||
export CXXFLAGS="$CFLAGS -sNO_DISABLE_EXCEPTION_CATCHING $EXTRA_CXXFLAGS"
|
||||
export LDFLAGS=" \
|
||||
@ -31,17 +18,10 @@ export LDFLAGS=" \
|
||||
-sMODULARIZE \
|
||||
-sMAIN_MODULE \
|
||||
-sNO_DISABLE_EXCEPTION_CATCHING \
|
||||
-sWASM_BIGINT \
|
||||
$EXTRA_LD_FLAGS \
|
||||
"
|
||||
|
||||
# This needs to test false if there exists an environment variable called
|
||||
# WASM_BIGINT whose contents are empty. Don't use +x.
|
||||
if [ -n "${WASM_BIGINT}" ] ; then
|
||||
export LDFLAGS+=" -sWASM_BIGINT"
|
||||
else
|
||||
export LDFLAGS+=" -sEXPORTED_RUNTIME_METHODS='getTempRet0,setTempRet0'"
|
||||
fi
|
||||
|
||||
# Rename main functions to test__filename so we can link them together
|
||||
ls *c | sed 's!\(.*\)\.c!sed -i "s/main/test__\1/g" \0!g' | bash
|
||||
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
command -v emcc >/dev/null 2>&1 || {
|
||||
echo >&2 "emsdk could not be found. Aborting."
|
||||
|
||||
if ! [ -x "$(command -v emcc)" ]; then
|
||||
echo "Error: emcc could not be found." >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
@ -13,38 +14,20 @@ TARGET=$SOURCE_DIR/target
|
||||
mkdir -p "$TARGET"
|
||||
|
||||
# Define default arguments
|
||||
|
||||
# JS BigInt to Wasm i64 integration, disabled by default
|
||||
# This needs to test false if there exists an environment variable called
|
||||
# WASM_BIGINT whose contents are empty. Don't use +x.
|
||||
if [ -n "${WASM_BIGINT}" ]; then
|
||||
WASM_BIGINT=true
|
||||
else
|
||||
WASM_BIGINT=false
|
||||
fi
|
||||
DEBUG=false
|
||||
|
||||
# Parse arguments
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--wasm-bigint) WASM_BIGINT=true ;;
|
||||
--debug) DEBUG=true ;;
|
||||
*)
|
||||
echo "ERROR: Unknown parameter: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
--debug) DEBUG=true ;;
|
||||
*) echo "ERROR: Unknown parameter: $1" >&2; exit 1 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Common compiler flags
|
||||
export CFLAGS="-O3 -fPIC"
|
||||
if [ "$WASM_BIGINT" = "true" ]; then
|
||||
# We need to detect WASM_BIGINT support at compile time
|
||||
export CFLAGS+=" -DWASM_BIGINT"
|
||||
fi
|
||||
if [ "$DEBUG" = "true" ]; then
|
||||
export CFLAGS+=" -DDEBUG_F"
|
||||
fi
|
||||
if [ "$DEBUG" = "true" ]; then export CFLAGS+=" -DDEBUG_F"; fi
|
||||
export CXXFLAGS="$CFLAGS"
|
||||
|
||||
# Build paths
|
||||
|
||||
@ -1,39 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
# JS BigInt to Wasm i64 integration, disabled by default
|
||||
WASM_BIGINT=false
|
||||
|
||||
emcc_exists="$(command -v emcc)"
|
||||
if [ ! "${emcc_exists}" ]; then
|
||||
echo "Emscripten not on path"
|
||||
if ! [ -x "$(command -v emcc)" ]; then
|
||||
echo "Error: emcc could not be found." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Parse arguments
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--wasm-bigint) WASM_BIGINT=true ;;
|
||||
*)
|
||||
echo "ERROR: Unknown parameter: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Common compiler flags
|
||||
export CFLAGS="-fPIC $EXTRA_CFLAGS"
|
||||
if [ "$WASM_BIGINT" = "true" ]; then
|
||||
# We need to detect WASM_BIGINT support at compile time
|
||||
export CFLAGS+=" -DWASM_BIGINT"
|
||||
fi
|
||||
export CXXFLAGS="$CFLAGS -sNO_DISABLE_EXCEPTION_CATCHING $EXTRA_CXXFLAGS"
|
||||
export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -sASSERTIONS -sNO_DISABLE_EXCEPTION_CATCHING"
|
||||
if [ "$WASM_BIGINT" = "true" ]; then
|
||||
export LDFLAGS+=" -sWASM_BIGINT"
|
||||
else
|
||||
export LDFLAGS+=" -sEXPORTED_RUNTIME_METHODS='getTempRet0,setTempRet0'"
|
||||
fi
|
||||
export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -sASSERTIONS -sNO_DISABLE_EXCEPTION_CATCHING -sWASM_BIGINT"
|
||||
|
||||
# Specific variables for cross-compilation
|
||||
export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
int i=5;
|
||||
static int i=5;
|
||||
|
||||
void callback(void) { i++; }
|
||||
static void callback(void) { i++; }
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
int i=5;
|
||||
static int i=5;
|
||||
|
||||
void callback(void) { i++; }
|
||||
static void callback(void) { i++; }
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
int i=5;
|
||||
static int i=5;
|
||||
|
||||
void callback(void) { i++; }
|
||||
static void callback(void) { i++; }
|
||||
|
||||
|
||||
typedef struct
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
/* { dg-do run } */
|
||||
#include "ffitest.h"
|
||||
|
||||
int i=5;
|
||||
static int i=5;
|
||||
|
||||
void callback(void) { i++; }
|
||||
static void callback(void) { i++; }
|
||||
|
||||
|
||||
typedef struct
|
||||
|
||||
@ -80,7 +80,7 @@ int main (void)
|
||||
/* { dg-output "1 32765 127 -128: 32765" } */
|
||||
printf("res: %d\n", (signed short)res_call);
|
||||
/* { dg-output "\nres: 32765" } */
|
||||
CHECK(res_call == 32765);
|
||||
CHECK((signed short)res_call == 32765);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ int main (void)
|
||||
/* { dg-output "1 2 127 128: 258" } */
|
||||
printf("res: %d\n", (unsigned short)res_call);
|
||||
/* { dg-output "\nres: 258" } */
|
||||
CHECK(res_call == 258);
|
||||
CHECK((unsigned short)res_call == 258);
|
||||
|
||||
CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user