Compare commits

...

21 Commits

Author SHA1 Message Date
YAMAMOTO Takashi
2ccf51a39e wasi_socket_ext.c: fix error reporting
do not return __WASI_ERRNO_xxx error code where 0/-1 is more appropriate.

most of them were not harmful because the value of
__WASI_ERRNO_SUCCESS is 0.

the one with __WASI_ERRNO_NOPROTOOPT in socket() is
a user-visible bug.

tested with wamr-wasi-extensions/samples/socket-tcp-udp.

cf. https://github.com/bytecodealliance/wasm-micro-runtime/issues/4474
2025-07-15 13:24:35 +09:00
YAMAMOTO Takashi
2a952b371a
wasi_socket_ext.c: fix the number of getaddrinfo results (#4466)
Some checks are pending
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $AOT_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Blocked by required conditions
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $CLASSIC_INTERP_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Blocked by required conditions
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $FAST_INTERP_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Blocked by required conditions
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $FAST_JIT_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, aot, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, aot, $SIMD_TEST_OPTIONS) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, aot, $XIP_TEST_OPTIONS) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, classic-interp, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, fast-jit, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / build_llvm_libraries_on_windows (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_AOT=0) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_INTERP=0) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_CUSTOM_NAME_SECTION=1) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_DEBUG_INTERP=1) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_LIBC_UVWASI=0 -DWAMR_BUILD_LIBC_WASI=1) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_LIB_PTHREAD=1) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_LIB_WASI_THREADS=1) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_REF_TYPES=1) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_SIMD=1) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_BUILD_TAIL_CALL=1) (push) Waiting to run
compilation on windows-latest / build_iwasm (-DWAMR_DISABLE_HW_BOUND_CHECK=1) (push) Waiting to run
compilation on windows-latest / build_wamrc (${{ needs.build_llvm_libraries_on_windows.outputs.cache_key }}, windows-latest) (push) Blocked by required conditions
compilation on windows-latest / test (classic-interp, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (classic-interp, $MULTI_MODULES_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (classic-interp, $THREADS_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (classic-interp, $WASI_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (fast-interp, $DEFAULT_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (fast-interp, $MULTI_MODULES_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (fast-interp, $THREADS_TEST_OPTIONS) (push) Blocked by required conditions
compilation on windows-latest / test (fast-interp, $WASI_TEST_OPTIONS) (push) Blocked by required conditions
the case of zero results was especially broken.
2025-07-14 13:12:32 +08:00
TianlongLiang
b3158e643c
Fix typos (#4472)
* leave api name unchanged so don't break API
2025-07-14 13:12:08 +08:00
Liu Jia
c8f7a7fc1a
fix regression running_config.json (#4477) 2025-07-14 13:08:58 +08:00
YAMAMOTO Takashi
2c4a660c4c
posix os_socket_addr_resolve: relax compatibility check (#4469)
some getaddrinfo implementations sometimes return results with
ai_protocol=0.

cf. https://github.com/apache/nuttx/issues/16693

standard-wise, i couldn't find anything about ai_protocol in
susv4-2018 except the following text:

> The fields ai_family, ai_socktype, and ai_protocol shall be usable
> as the arguments to the socket() function to create a socket suitable
> for use with the returned address.

because ai_protocol is usually merely used to feed socket() and
socket() usually accepts 0, it's probably standard-wise ok for
getaddrinfo to return ai_protocol=0.
the major implementations of getaddrinfo (eg. kame) seem to return
specific values like ai_protocol=IPPROTO_TCP though.

anyway, for the purpose of this function, there is little point to
be strict on the host getaddrinfo behavior. this commit just relaxes
the check to be friendly to those getaddrinfo implementations.
2025-07-14 13:06:40 +08:00
YAMAMOTO Takashi
53feadc2b0
lib-socket: implement getsockopt(SOL_SOCKET,SO_TYPE) (#4458)
cf. https://github.com/bytecodealliance/wasm-micro-runtime/issues/4456
2025-07-14 13:06:33 +08:00
YAMAMOTO Takashi
5d48cfdbc0
introduce wasm_runtime_instantiate_ex2 (#4444)
* introduce wasm_runtime_instantiate_ex2

at this point, just a slightly inefficiant functionality
equivalent of wasm_runtime_instantiate_ex.
however, unlike wasm_runtime_instantiate_ex, this one is designed
to be extendable without breaking the user-visible ABI.
because the definition of InstantiationArgs2 is not exposed to
users, we can safely add new members to it.

this commit also makes wasm_runtime_instantiate_ex a wrapper
of wasm_runtime_instantiate_ex2.

if this goes well, maybe it's a good idea to apply a similar
pattern to RuntimeInitArgs, LoadArgs, SharedHeapInitArgs, etc.
i started with InstantiationArgs just because i happen to have
a need to extend it for wasi-nn.

cf.
https://github.com/bytecodealliance/wasm-micro-runtime/issues/4364
https://github.com/bytecodealliance/wasm-micro-runtime/issues/4331

* product-mini/platforms/posix: use wasm_runtime_instantiate_ex2
2025-07-14 13:06:23 +08:00
Zhenwei Jin
65d3ffa7a4
add validation for recursive type count in loader (#4440) 2025-07-14 13:06:08 +08:00
liang.he
47c7c85ac2
Bump version to 2.4.0 (#4483) 2025-07-14 11:06:03 +08:00
YAMAMOTO Takashi
17be90d8f0
posix os_socket_addr_resolve: return the consistent max_info_size (#4467)
Some checks failed
compilation on macos / build_iwasm (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, -DWAMR_DISABLE_HW_BOUND_CHECK=1, $FAST_INTERP_BUILD_OPTIONS, macos-13, darwin) (push) Has been cancelled
compilation on macos / build_iwasm (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, -DWAMR_DISABLE_HW_BOUND_CHECK=1, $LLVM_EAGER_JIT_BUILD_OPTIONS, macos-13, darwin) (push) Has been cancelled
compilation on macos / build_iwasm (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, -DWAMR_DISABLE_HW_BOUND_CHECK=1, $LLVM_LAZY_JIT_BUILD_OPTIONS, macos-13, darwin) (push) Has been cancelled
compilation on macos / build_samples_wasm_c_api (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, $AOT_BUILD_OPTIONS, macos-13) (push) Has been cancelled
compilation on macos / build_samples_wasm_c_api (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, $CLASSIC_INTERP_BUILD_OPTIONS, macos-13) (push) Has been cancelled
compilation on macos / build_samples_wasm_c_api (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, $FAST_INTERP_BUILD_OPTIONS, macos-13) (push) Has been cancelled
compilation on macos / build_samples_wasm_c_api (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, $FAST_JIT_BUILD_OPTIONS, macos-13) (push) Has been cancelled
compilation on macos / build_samples_wasm_c_api (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, $LLVM_EAGER_JIT_BUILD_OPTIONS, macos-13) (push) Has been cancelled
compilation on macos / build_samples_wasm_c_api (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, $LLVM_LAZY_JIT_BUILD_OPTIONS, macos-13) (push) Has been cancelled
compilation on macos / build_samples_wasm_c_api (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, $MULTI_TIER_JIT_BUILD_OPTIONS, macos-13) (push) Has been cancelled
compilation on macos / build_samples_others (${{ needs.build_llvm_libraries_on_arm_macos.outputs.cache_key }}, macos-14) (push) Has been cancelled
compilation on macos / build_samples_others (${{ needs.build_llvm_libraries_on_intel_macos.outputs.cache_key }}, macos-13) (push) Has been cancelled
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $AOT_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Has been cancelled
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $CLASSIC_INTERP_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Has been cancelled
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $FAST_INTERP_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Has been cancelled
compilation on SGX / run_samples_file (-DWAMR_BUILD_SGX_IPFS=1, $FAST_JIT_BUILD_OPTIONS, ${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, linux-sgx) (push) Has been cancelled
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, aot, $DEFAULT_TEST_OPTIONS) (push) Has been cancelled
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, aot, $SIMD_TEST_OPTIONS) (push) Has been cancelled
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, aot, $XIP_TEST_OPTIONS) (push) Has been cancelled
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, classic-interp, $DEFAULT_TEST_OPTIONS) (push) Has been cancelled
compilation on SGX / spec_test_default (${{ needs.build_llvm_libraries.outputs.cache_key }}, ubuntu-22.04, fast-jit, $DEFAULT_TEST_OPTIONS) (push) Has been cancelled
compilation on windows-latest / build_wamrc (${{ needs.build_llvm_libraries_on_windows.outputs.cache_key }}, windows-latest) (push) Has been cancelled
compilation on windows-latest / test (classic-interp, $DEFAULT_TEST_OPTIONS) (push) Has been cancelled
compilation on windows-latest / test (classic-interp, $MULTI_MODULES_TEST_OPTIONS) (push) Has been cancelled
compilation on windows-latest / test (classic-interp, $THREADS_TEST_OPTIONS) (push) Has been cancelled
compilation on windows-latest / test (classic-interp, $WASI_TEST_OPTIONS) (push) Has been cancelled
compilation on windows-latest / test (fast-interp, $DEFAULT_TEST_OPTIONS) (push) Has been cancelled
compilation on windows-latest / test (fast-interp, $MULTI_MODULES_TEST_OPTIONS) (push) Has been cancelled
compilation on windows-latest / test (fast-interp, $THREADS_TEST_OPTIONS) (push) Has been cancelled
compilation on windows-latest / test (fast-interp, $WASI_TEST_OPTIONS) (push) Has been cancelled
return the same value for max_info_size regardless of addr_info_size.
2025-07-10 13:42:57 +08:00
Zhenwei Jin
9e92f5ebe1
fix a wamrc debug mode compile issue (#4470) 2025-07-10 08:29:31 +08:00
Zhenwei Jin
334b4f8cb5
Add readme for extended const (#4471) 2025-07-10 08:29:03 +08:00
YAMAMOTO Takashi
56f87b7ee9
wasi-nn: do not pretend to support legacy abi in openvino and llamacpp (#4468)
as tested by core/iwasm/libraries/wasi-nn/test/test_tensorflow.c,
the legacy "wasi_nn" abi uses the number of fp32 for get_output.
because these backends don't implement the abi, bail out explicitly
in build time.

cf.
https://github.com/bytecodealliance/wasm-micro-runtime/issues/4376
2025-07-10 08:28:08 +08:00
YAMAMOTO Takashi
933e49df18
appease a few compiler warnings (-Wstrict-prototypes) (#4465) 2025-07-10 08:28:00 +08:00
Zhenwei Jin
d6fc18e197
enable aux stack frame for aot compiler fuzz test (#4462) 2025-07-10 08:27:42 +08:00
dependabot[bot]
cd4712d939
build(deps): Bump github/codeql-action from 3.29.1 to 3.29.2 (#4459)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.29.1 to 3.29.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v3.29.1...v3.29.2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.29.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-10 08:27:32 +08:00
Liu Jia
903a5c1f8c
improve logic of heap_type validation when ref.null (#4372)
* Follow-up to PR #4300: prevent potential overflow

PR #4300 introduced the rationale for validating heap_type.
This patch moves the validation before the computation of
type1 to prevent potential overflow.
2025-07-10 08:27:11 +08:00
YAMAMOTO Takashi
fbd27e5e03
wasi_nn_llamacpp.c: explicitly reject unimplemented input index (#4446)
note: wasmedge seems to accept index 1 for metadata. we don't
implement it.
2025-07-09 10:35:46 +08:00
liang.he
d3b0b5c066
Add security issue runbook (#4450)
This runbook provides step-by-step guidance on handling a security advisory
2025-07-08 09:26:45 +08:00
YAMAMOTO Takashi
0eceed2ba9
wasi: avoid user-triggerable 0-sized allocations (#4452)
might fix https://github.com/bytecodealliance/wasm-micro-runtime/issues/4451
2025-07-08 09:25:50 +08:00
TianlongLiang
7d05dbc988
Support extended constant expressions (#4432)
* implement extended const expr (#4318)
* add a toggle to enable extended const on wamrc (#4412)
2025-07-07 13:34:02 +08:00
52 changed files with 2248 additions and 511 deletions

View File

@ -53,7 +53,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.29.1
uses: github/codeql-action/init@v3.29.2
with:
languages: ${{ matrix.language }}
@ -70,7 +70,7 @@ jobs:
- run: |
./.github/scripts/codeql_buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.29.1
uses: github/codeql-action/analyze@v3.29.2
with:
category: "/language:${{matrix.language}}"
upload: false
@ -99,7 +99,7 @@ jobs:
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
- name: Upload CodeQL results to code scanning
uses: github/codeql-action/upload-sarif@v3.29.1
uses: github/codeql-action/upload-sarif@v3.29.2
with:
sarif_file: ${{ steps.step1.outputs.sarif-output }}
category: "/language:${{matrix.language}}"

View File

@ -69,6 +69,7 @@ env:
GC_TEST_OPTIONS: "-s spec -G -b -P"
MEMORY64_TEST_OPTIONS: "-s spec -W -b -P"
MULTI_MEMORY_TEST_OPTIONS: "-s spec -E -b -P"
EXTENDED_CONST_EXPR_TEST_OPTIONS: "-s spec -N -b -P"
permissions:
contents: read
@ -164,6 +165,7 @@ jobs:
"-DWAMR_BUILD_MEMORY64=1",
"-DWAMR_BUILD_MULTI_MEMORY=1",
"-DWAMR_BUILD_SHARED=1",
"-DWAMR_BUILD_EXTENDED_CONST_EXPR=1",
]
os: [ubuntu-22.04]
platform: [android, linux]
@ -609,6 +611,7 @@ jobs:
$GC_TEST_OPTIONS,
$MEMORY64_TEST_OPTIONS,
$MULTI_MEMORY_TEST_OPTIONS,
$EXTENDED_CONST_EXPR_TEST_OPTIONS,
]
include:
- os: ubuntu-22.04

View File

@ -142,6 +142,7 @@ jobs:
"-DWAMR_BUILD_SIMD=1",
"-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1",
"-DWAMR_BUILD_EXTENDED_CONST_EXPR=1",
]
os: [macos-13]
platform: [darwin]

View File

@ -100,6 +100,7 @@ jobs:
"-DWAMR_BUILD_MULTI_MODULE=1",
"-DWAMR_BUILD_PERF_PROFILING=1",
"-DWAMR_BUILD_REF_TYPES=1",
"-DWAMR_BUILD_EXTENDED_CONST_EXPR=1",
# doesn't support
"-DWAMR_BUILD_SIMD=0",
"-DWAMR_BUILD_TAIL_CALL=1",

View File

@ -37,6 +37,7 @@ env:
MULTI_TIER_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=1"
# For Spec Test
DEFAULT_TEST_OPTIONS: "-s spec -b -P"
EXTENDED_CONST_EXPR_TEST_OPTIONS: "-s spec -b -P -N"
MULTI_MODULES_TEST_OPTIONS: "-s spec -b -P -M"
SIMD_TEST_OPTIONS: "-s spec -b -P -S"
THREADS_TEST_OPTIONS: "-s spec -b -P -p"
@ -128,6 +129,7 @@ jobs:
"-DWAMR_BUILD_MEMORY64=1",
"-DWAMR_BUILD_MULTI_MEMORY=1",
"-DWAMR_BUILD_SHARED=1",
"-DWAMR_BUILD_EXTENDED_CONST_EXPR=1",
]
os: [ubuntu-22.04]
platform: [android, linux]
@ -588,6 +590,7 @@ jobs:
$DEFAULT_TEST_OPTIONS,
$MULTI_MODULES_TEST_OPTIONS,
$SIMD_TEST_OPTIONS,
$EXTENDED_CONST_EXPR_TEST_OPTIONS,
$THREADS_TEST_OPTIONS,
$WASI_TEST_OPTIONS,
]

View File

@ -60,6 +60,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@4c57370d0304fbff638216539f81d9163f77712a
uses: github/codeql-action/upload-sarif@b69421388d5449cc5a5e1ca344d71926bda69e07
with:
sarif_file: results.sarif

View File

@ -48,6 +48,7 @@ WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm)
- [Reference Types](https://github.com/WebAssembly/reference-types), ref to [document](doc/ref_types.md) and [sample](samples/ref-types)
- [Bulk memory operations](https://github.com/WebAssembly/bulk-memory-operations), [Shared memory](https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md#shared-linear-memory), [Memory64](https://github.com/WebAssembly/memory64)
- [Tail-call](https://github.com/WebAssembly/tail-call), [Garbage Collection](https://github.com/WebAssembly/gc), [Exception Handling](https://github.com/WebAssembly/exception-handling)
- [Extended Constant Expressions](https://github.com/WebAssembly/extended-const)
### Supported architectures and platforms
The WAMR VMcore supports the following architectures:

View File

@ -1,3 +1,122 @@
## WAMR-2.4.0
### Breaking Changes
- Refactor copy callstack feature (#4401)
- Enable WAMR_BUILD_WASI_EPHEMERAL_NN by default (#4381)
- Enable aot memory64 sw bounds checks by default (#4350)
### New Features
- Support extended constant expressions (#4432)
- Shared heap enhancements for Interpreter and AOT (#4400)
### Bug Fixes
- posix os_socket_addr_resolve: return the consistent max_info_size (#4467)
- fix a wamrc debug mode compile issue (#4470)
- wasi-nn: do not pretend to support legacy abi in openvino and llamacpp (#4468)
- appease a few compiler warnings (-Wstrict-prototypes) (#4465)
- enable aux stack frame for aot compiler fuzz test (#4462)
- improve logic of `heap_type` validation when `ref.null` (#4372)
- wasi_nn_llamacpp.c: explicitly reject unimplemented input index (#4446)
- wasi: avoid user-triggerable 0-sized allocations (#4452)
- Fix socket shutdown (#12) (#4449)
- wasi_nn_llamacpp.c: validate input tensor type/dimensions (#4442)
- wasi_nn_llamacpp.c: reject invalid graph and execution context (#4422)
- wasi_nn_openvino.c: avoid self-assignment warning (#4434)
- Fix potential integer overflow issues (#4429)
- Improve run.py of regression (#4417)
- wasi-nn: reduce code duplication a bit (#4433)
- Refactor AOTObjectData definition to use a forward declaration (#4428)
- CI: revert SGX retry attempts (#4421)
- loader: fix a potential overflow issue (#4427)
- wasi_nn_openvino.c: fix a debug build (#4416)
- Fix few shadow warnings (#4409)
- wasi_nn_llamacpp.c: remove an unused variable (#4415)
- wasi_nn_llamacpp.c: fix buffer overruns in set_input (#4420)
- wasi-nn: make the host use the wasi_ephemeral_nn version of tensor_data (#4411)
- Collective fix (#4413)
- fix bug in bh_vector when extending (#4414)
- wasi_nn_llamacpp.c: make this compilable (#4403)
- Fix handling of non-nullable global_type during global import (#4408)
- loader: add type index checking (#4402)
- wasi_nn_tensorflowlite.cpp: fix get_output return size (#4390)
- wasi-nn: fix context lifetime issues (#4396)
- CI: fix the description of upload_url (#4407)
- wamr-wasi-extensions/socket: disable reference-types (#4392)
- wasi_nn_openvino.c: implement multiple models per instance (#4380)
- Improve spec test execution by adding retry logic for transient errors (#4393)
- wasi-nn: add minimum serialization on WASINNContext (#4387)
- deprecate legacy WAMR-specific "wasi_nn" module (#4382)
- wasi-nn: fix tensor_data abi for wasi_ephemeral_nn (#4379)
- core/iwasm/libraries/wasi-nn/test: use the correct version of keras (#4383)
- Fix several issues related to night-run CI and test scripts. (#4385)
- wasi_nn_tensorflowlite.cpp: reject non-fp32 input earlier (#4388)
- core/iwasm/libraries/wasi-nn/test/build.sh: add a tip for intel mac (#4389)
- wasi-nn: don't try to deinit uninitialized backend (#4375)
- wasi-nn: apply the shared library hack to darwin as well (#4374)
- add nn-cli example (#4373)
- wasi_nn_openvino.c: remove pre/postprocessing and layout assumptions (#4361)
- send an empty/error reply from server (#4362)
- wasi_nn_openvino.c: add a missing buffer overflow check in get_output (#4353)
- wasi_ephemeral_nn.h: prefix identfiers to avoid too generic names (#4358)
- wamr-wasi-extensions: add lib-socket things (#4360)
- wasi_nn_openvino.c: remove broken xml check (#4365)
- add validation for array type in load_init_expr(GC only) (#4370)
- wasi-nn: fix backend leak on multiple loads (#4366)
- Collective fix for typos and minor bugs (#4369)
- Modify AOT static PGO to conform to llvm-18 and add a CI job to test static PGO on the coremark benchmark (#4345)
- Update WABT downloads URL (#4357)
- clean up incompatible running mode checks in test script and ci (#4342)
- Follow #4268 to deprecate wamr_ide-related components (#4341)
- Update type validation in load_table_import() and load_table() (#4296)
- wasi_nn_openvino.c: remove the tensor layout adjustment logic (#4308)
- add heap-type check for GC when ref.null (#4300)
- wasi_nn_types.h: remove a seemingly stale comment (#4348)
- wasi_socket_ext.c: avoid tls to make this library-friendly (#4338)
- wasi-nn: do not assign wasi_nn_ctx->backend multiple times (#4329)
- wasi_nn.h: make this compatible with wasi_ephemeral_nn (#4330)
- remove temporary wasi-libc build steps from CI workflows (#4343)
- wasi-nn: fix the size of tensor->type (#4333)
- wasi-nn: move some host-only things out of wasi_nn_types.h (#4334)
- Collective fix: fix some typos (#4337)
- Update binary compression steps to follow symlinks for actual files (#4321)
- Add wamrc compilation into Windows CI workflow (#4327)
- wasi-nn: remove unused wasi_nn_dump_tensor_dimension prototype (#4325)
- wasi_nn.h: add import_name attribute (#4328)
- wasi-nn: protect the backend lookup table with a lock (#4319)
- handle nullable heap reference types in import section (#4302)
- wasi_nn_openvino.c: make this buildable (#4305)
- wasi-nn: fix shared library filenames for macOS (#4306)
- fix wasi-nn abi definitions (#4307)
- wasi-nn: remove "backends" argument from detect_and_load_backend() (#4309)
- wasi_nn_openvino.c: fix a few printf formats (#4310)
- Bump uvwasi to latest commit #392e1f1 (#4312)
### Enhancements
- Add readme for extended const (#4471)
- Add security issue runbook (#4450)
- docs: fix cmake variable typo (#4441)
- CI: add wamr_wasi_extensions to the release assets (#4425)
- CI: build wamr-wasi-extensions (#4394)
- improve installation steps for wasi-sdk and wabt on Windows (#4359)
- wamr-wasi-extensions: add a cmake package to provide our wasi extension (#4344)
- Update Dockerfile for Zephyr SDK and Zephyr-project versioning (#4335)
- add load_by_name in wasi-nn (#4298)
### Others
- build(deps): Bump ossf/scorecard-action from 2.4.1 to 2.4.2 (#4315)
- build(deps): Bump github/codeql-action from 3.29.1 to 3.29.2 (#4459)
- build(deps): Bump github/codeql-action from 3.29.0 to 3.29.1 (#4436)
- build(deps): Bump github/codeql-action from 3.28.19 to 3.29.0 (#4371)
- build(deps): Bump github/codeql-action from 3.28.18 to 3.28.19 (#4346)
- build(deps): Bump requests from 2.32.3 to 2.32.4 in /build-scripts (#4349)
---
## WAMR-2.3.1
### Breaking Changes

View File

@ -211,6 +211,10 @@ if (NOT DEFINED WAMR_BUILD_TAIL_CALL)
set (WAMR_BUILD_TAIL_CALL 0)
endif ()
if (NOT DEFINED WAMR_BUILD_EXTENDED_CONST_EXPR)
set (WAMR_BUILD_EXTENDED_CONST_EXPR 0)
endif ()
########################################
# Compilation options to marco
########################################
@ -673,7 +677,13 @@ if (WAMR_BUILD_INSTRUCTION_METERING EQUAL 1)
message (" Instruction metering enabled")
add_definitions (-DWASM_ENABLE_INSTRUCTION_METERING=1)
endif ()
if (WAMR_BUILD_EXTENDED_CONST_EXPR EQUAL 1)
message (" Extended constant expression enabled")
add_definitions(-DWASM_ENABLE_EXTENDED_CONST_EXPR=1)
else()
message (" Extended constant expression disabled")
add_definitions(-DWASM_ENABLE_EXTENDED_CONST_EXPR=0)
endif ()
########################################
# Show Phase4 Wasm proposals status.
########################################
@ -687,6 +697,7 @@ message (
" \"WebAssembly C and C++ API\"\n"
" Configurable. 0 is OFF. 1 is ON:\n"
" \"Bulk Memory Operation\" via WAMR_BUILD_BULK_MEMORY: ${WAMR_BUILD_BULK_MEMORY}\n"
" \"Extended Constant Expressions\" via WAMR_BUILD_EXTENDED_CONST_EXPR: ${WAMR_BUILD_EXTENDED_CONST_EXPR}\n"
" \"Fixed-width SIMD\" via WAMR_BUILD_SIMD: ${WAMR_BUILD_SIMD}\n"
" \"Garbage collection\" via WAMR_BUILD_GC: ${WAMR_BUILD_GC}\n"
" \"Legacy Exception handling\" via WAMR_BUILD_EXCE_HANDLING: ${WAMR_BUILD_EXCE_HANDLING}\n"
@ -701,7 +712,6 @@ message (
" \"Branch Hinting\"\n"
" \"Custom Annotation Syntax in the Text Format\"\n"
" \"Exception handling\"\n"
" \"Extended Constant Expressions\"\n"
" \"Import/Export of Mutable Globals\"\n"
" \"JS String Builtins\"\n"
" \"Relaxed SIMD\"\n"

View File

@ -7,8 +7,8 @@ if(NOT WAMR_ROOT_DIR)
endif()
set(WAMR_VERSION_MAJOR 2)
set(WAMR_VERSION_MINOR 3)
set(WAMR_VERSION_PATCH 1)
set(WAMR_VERSION_MINOR 4)
set(WAMR_VERSION_PATCH 0)
message("-- WAMR version: ${WAMR_VERSION_MAJOR}.${WAMR_VERSION_MINOR}.${WAMR_VERSION_PATCH}")

View File

@ -720,4 +720,8 @@ unless used elsewhere */
#define WASM_ENABLE_INSTRUCTION_METERING 0
#endif
#ifndef WASM_ENABLE_EXTENDED_CONST_EXPR
#define WASM_ENABLE_EXTENDED_CONST_EXPR 0
#endif
#endif /* end of _CONFIG_H_ */

View File

@ -968,6 +968,35 @@ fail:
return false;
}
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
static void
destroy_init_expr(InitializerExpression *expr)
{
#if WASM_ENABLE_GC != 0
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
wasm_runtime_free(expr->u.unary.v.data);
}
#endif
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
// free left expr and right expr for binary oprand
if (!is_expr_binary_op(expr->init_expr_type)) {
return;
}
if (expr->u.binary.l_expr) {
destroy_init_expr_recursive(expr->u.binary.l_expr);
}
if (expr->u.binary.r_expr) {
destroy_init_expr_recursive(expr->u.binary.r_expr);
}
expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
#endif
}
#endif /* end of WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0 \
*/
static void
destroy_import_memories(AOTImportMemory *import_memories)
{
@ -993,6 +1022,10 @@ destroy_mem_init_data_list(AOTModule *module, AOTMemInitData **data_list,
/* If the module owns the binary data, free the bytes buffer */
if (module->is_binary_freeable && data_list[i]->bytes)
wasm_runtime_free(data_list[i]->bytes);
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
destroy_init_expr(&data_list[i]->offset);
#endif
/* Free the data segment structure itself */
wasm_runtime_free(data_list[i]);
}
@ -1043,11 +1076,11 @@ load_mem_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
uint32 byte_count;
uint32 is_passive;
uint32 memory_index;
InitializerExpression init_value;
InitializerExpression offset_expr;
read_uint32(buf, buf_end, is_passive);
read_uint32(buf, buf_end, memory_index);
if (!load_init_expr(&buf, buf_end, module, &init_value, error_buf,
if (!load_init_expr(&buf, buf_end, module, &offset_expr, error_buf,
error_buf_size)) {
return false;
}
@ -1062,8 +1095,7 @@ load_mem_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
data_list[i]->is_passive = (bool)is_passive;
data_list[i]->memory_index = memory_index;
#endif
data_list[i]->offset.init_expr_type = init_value.init_expr_type;
data_list[i]->offset.u = init_value.u;
data_list[i]->offset = offset_expr;
data_list[i]->byte_count = byte_count;
data_list[i]->bytes = NULL;
/* If the module owns the binary data, clone the bytes buffer */
@ -1148,18 +1180,6 @@ fail:
return false;
}
#if WASM_ENABLE_GC != 0
static void
destroy_init_expr(InitializerExpression *expr)
{
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
wasm_runtime_free(expr->u.data);
}
}
#endif /* end of WASM_ENABLE_GC != 0 */
static void
destroy_import_tables(AOTImportTable *import_tables)
{
@ -1183,6 +1203,9 @@ destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count)
for (j = 0; j < data_list[i]->value_count; j++) {
destroy_init_expr(&data_list[i]->init_values[j]);
}
#endif
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
destroy_init_expr(&data_list[i]->offset);
#endif
wasm_runtime_free(data_list[i]);
}
@ -1208,34 +1231,34 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
break;
case INIT_EXPR_TYPE_I32_CONST:
case INIT_EXPR_TYPE_F32_CONST:
read_uint32(buf, buf_end, expr->u.i32);
read_uint32(buf, buf_end, expr->u.unary.v.i32);
break;
case INIT_EXPR_TYPE_I64_CONST:
case INIT_EXPR_TYPE_F64_CONST:
read_uint64(buf, buf_end, expr->u.i64);
read_uint64(buf, buf_end, expr->u.unary.v.i64);
break;
case INIT_EXPR_TYPE_V128_CONST:
i64x2 = (uint64 *)expr->u.v128.i64x2;
i64x2 = (uint64 *)expr->u.unary.v.v128.i64x2;
CHECK_BUF(buf, buf_end, sizeof(uint64) * 2);
wasm_runtime_read_v128(buf, &i64x2[0], &i64x2[1]);
buf += sizeof(uint64) * 2;
break;
case INIT_EXPR_TYPE_GET_GLOBAL:
read_uint32(buf, buf_end, expr->u.global_index);
read_uint32(buf, buf_end, expr->u.unary.v.global_index);
break;
/* INIT_EXPR_TYPE_FUNCREF_CONST can be used when
both reference types and GC are disabled */
case INIT_EXPR_TYPE_FUNCREF_CONST:
read_uint32(buf, buf_end, expr->u.ref_index);
read_uint32(buf, buf_end, expr->u.unary.v.ref_index);
break;
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0
case INIT_EXPR_TYPE_REFNULL_CONST:
read_uint32(buf, buf_end, expr->u.ref_index);
read_uint32(buf, buf_end, expr->u.unary.v.ref_index);
break;
#endif /* end of WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0 */
#if WASM_ENABLE_GC != 0
case INIT_EXPR_TYPE_I31_NEW:
read_uint32(buf, buf_end, expr->u.i32);
read_uint32(buf, buf_end, expr->u.unary.v.i32);
break;
case INIT_EXPR_TYPE_STRUCT_NEW:
{
@ -1256,7 +1279,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
free_if_fail = true;
init_values->count = field_count;
init_values->type_idx = type_idx;
expr->u.data = init_values;
expr->u.unary.v.data = init_values;
if (type_idx >= module->type_count) {
set_error_buf(error_buf, error_buf_size,
@ -1294,7 +1317,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
break;
}
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
read_uint32(buf, buf_end, expr->u.type_index);
read_uint32(buf, buf_end, expr->u.unary.v.type_index);
break;
case INIT_EXPR_TYPE_ARRAY_NEW:
case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
@ -1317,8 +1340,8 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
}
if (init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
expr->u.array_new_default.type_index = type_idx;
expr->u.array_new_default.length = length;
expr->u.unary.v.array_new_default.type_index = type_idx;
expr->u.unary.v.array_new_default.length = length;
}
else {
uint32 i, elem_size, elem_data_count;
@ -1329,7 +1352,7 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
return false;
}
free_if_fail = true;
expr->u.data = init_values;
expr->u.unary.v.data = init_values;
init_values->type_idx = type_idx;
init_values->length = length;
@ -1357,6 +1380,34 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
break;
}
#endif /* end of WASM_ENABLE_GC != 0 */
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
{
expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
if (!(expr->u.binary.l_expr =
loader_malloc(sizeof(InitializerExpression), error_buf,
error_buf_size))) {
goto fail;
}
if (!load_init_expr(&buf, buf_end, module, expr->u.binary.l_expr,
error_buf, error_buf_size))
goto fail;
if (!(expr->u.binary.r_expr =
loader_malloc(sizeof(InitializerExpression), error_buf,
error_buf_size))) {
goto fail;
}
if (!load_init_expr(&buf, buf_end, module, expr->u.binary.r_expr,
error_buf, error_buf_size))
goto fail;
break;
}
#endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */
default:
set_error_buf(error_buf, error_buf_size, "invalid init expr type.");
return false;
@ -1369,10 +1420,13 @@ load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
fail:
#if WASM_ENABLE_GC != 0
if (free_if_fail) {
wasm_runtime_free(expr->u.data);
wasm_runtime_free(expr->u.unary.v.data);
}
#else
(void)free_if_fail;
#endif
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
destroy_init_expr(expr);
#endif
return false;
}
@ -1535,14 +1589,16 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
/* Create each table data segment */
for (i = 0; i < module->table_init_data_count; i++) {
uint32 mode, elem_type;
uint32 table_index, init_expr_type, value_count;
uint64 init_expr_value, size1;
uint32 table_index, value_count;
uint64 size1;
InitializerExpression offset_expr;
read_uint32(buf, buf_end, mode);
read_uint32(buf, buf_end, elem_type);
read_uint32(buf, buf_end, table_index);
read_uint32(buf, buf_end, init_expr_type);
read_uint64(buf, buf_end, init_expr_value);
if (!load_init_expr(&buf, buf_end, module, &offset_expr, error_buf,
error_buf_size))
return false;
#if WASM_ENABLE_GC != 0
if (wasm_is_type_multi_byte_type(elem_type)) {
uint16 ref_type, nullable;
@ -1588,8 +1644,7 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
}
}
#endif
data_list[i]->offset.init_expr_type = (uint8)init_expr_type;
data_list[i]->offset.u.i64 = (int64)init_expr_value;
data_list[i]->offset = offset_expr;
data_list[i]->value_count = value_count;
for (j = 0; j < data_list[i]->value_count; j++) {
if (!load_init_expr(&buf, buf_end, module,
@ -4500,7 +4555,7 @@ aot_unload(AOTModule *module)
destroy_import_globals(module->import_globals);
if (module->globals) {
#if WASM_ENABLE_GC != 0
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
uint32 i;
for (i = 0; i < module->global_count; i++) {
destroy_init_expr(&module->globals[i].init_expr);
@ -4656,7 +4711,7 @@ aot_unload(AOTModule *module)
}
uint32
aot_get_plt_table_size()
aot_get_plt_table_size(void)
{
return get_plt_table_size();
}

View File

@ -289,18 +289,21 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module,
switch (flag) {
case INIT_EXPR_TYPE_GET_GLOBAL:
{
if (!check_global_init_expr(module, init_expr->u.global_index,
if (!check_global_init_expr(module,
init_expr->u.unary.v.global_index,
error_buf, error_buf_size)) {
return false;
}
if (init_expr->u.global_index < module->import_global_count) {
if (init_expr->u.unary.v.global_index
< module->import_global_count) {
PUT_REF_TO_ADDR(
addr, module->import_globals[init_expr->u.global_index]
.global_data_linked.gc_obj);
addr,
module->import_globals[init_expr->u.unary.v.global_index]
.global_data_linked.gc_obj);
}
else {
uint32 global_idx =
init_expr->u.global_index - module->import_global_count;
uint32 global_idx = init_expr->u.unary.v.global_index
- module->import_global_count;
return assign_table_init_value(
module_inst, module, &module->globals[global_idx].init_expr,
addr, error_buf, error_buf_size);
@ -316,7 +319,7 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module,
case INIT_EXPR_TYPE_FUNCREF_CONST:
{
WASMFuncObjectRef func_obj = NULL;
uint32 func_idx = init_expr->u.u32;
uint32 func_idx = init_expr->u.unary.v.u32;
if (func_idx != UINT32_MAX) {
if (!(func_obj =
@ -331,7 +334,8 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module,
}
case INIT_EXPR_TYPE_I31_NEW:
{
WASMI31ObjectRef i31_obj = wasm_i31_obj_new(init_expr->u.i32);
WASMI31ObjectRef i31_obj =
wasm_i31_obj_new(init_expr->u.unary.v.i32);
PUT_REF_TO_ADDR(addr, i31_obj);
break;
}
@ -345,11 +349,12 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module,
uint32 type_idx;
if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
init_values = (WASMStructNewInitValues *)init_expr->u.data;
init_values =
(WASMStructNewInitValues *)init_expr->u.unary.v.data;
type_idx = init_values->type_idx;
}
else {
type_idx = init_expr->u.type_index;
type_idx = init_expr->u.unary.v.type_index;
}
struct_type = (WASMStructType *)module->types[type_idx];
@ -398,12 +403,13 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module,
uint32 type_idx, len;
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
type_idx = init_expr->u.array_new_default.type_index;
len = init_expr->u.array_new_default.length;
type_idx = init_expr->u.unary.v.array_new_default.type_index;
len = init_expr->u.unary.v.array_new_default.length;
arr_init_val = &empty_val;
}
else {
init_values = (WASMArrayNewInitValues *)init_expr->u.data;
init_values =
(WASMArrayNewInitValues *)init_expr->u.unary.v.data;
type_idx = init_values->type_idx;
len = init_values->length;
@ -454,6 +460,90 @@ assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module,
}
#endif /* end of WASM_ENABLE_GC != 0 */
static bool
get_init_value_recursive(AOTModuleInstance *module_inst, AOTModule *module,
InitializerExpression *expr, WASMValue *value,
char *error_buf, uint32 error_buf_size)
{
uint8 flag = expr->init_expr_type;
switch (flag) {
case INIT_EXPR_TYPE_GET_GLOBAL:
{
if (!check_global_init_expr(module, expr->u.unary.v.global_index,
error_buf, error_buf_size)) {
return false;
}
#if WASM_ENABLE_GC == 0
*value = module->import_globals[expr->u.unary.v.global_index]
.global_data_linked;
#else
if (expr->u.unary.v.global_index < module->import_global_count) {
*value = module->import_globals[expr->u.unary.v.global_index]
.global_data_linked;
}
else {
*value = module
->globals[expr->u.unary.v.global_index
- module->import_global_count]
.init_expr.u.unary.v;
}
#endif
break;
}
case INIT_EXPR_TYPE_I32_CONST:
case INIT_EXPR_TYPE_I64_CONST:
{
*value = expr->u.unary.v;
break;
}
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
{
WASMValue l_value, r_value;
if (!get_init_value_recursive(module_inst, module,
expr->u.binary.l_expr, &l_value,
error_buf, error_buf_size)) {
return false;
}
if (!get_init_value_recursive(module_inst, module,
expr->u.binary.r_expr, &r_value,
error_buf, error_buf_size)) {
return false;
}
if (flag == INIT_EXPR_TYPE_I32_ADD) {
value->i32 = l_value.i32 + r_value.i32;
}
else if (flag == INIT_EXPR_TYPE_I32_SUB) {
value->i32 = l_value.i32 - r_value.i32;
}
else if (flag == INIT_EXPR_TYPE_I32_MUL) {
value->i32 = l_value.i32 * r_value.i32;
}
else if (flag == INIT_EXPR_TYPE_I64_ADD) {
value->i64 = l_value.i64 + r_value.i64;
}
else if (flag == INIT_EXPR_TYPE_I64_SUB) {
value->i64 = l_value.i64 - r_value.i64;
}
else if (flag == INIT_EXPR_TYPE_I64_MUL) {
value->i64 = l_value.i64 * r_value.i64;
}
break;
}
#endif
default:
return false;
}
return true;
}
static bool
global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
char *error_buf, uint32 error_buf_size)
@ -482,30 +572,24 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
flag = init_expr->init_expr_type;
switch (flag) {
case INIT_EXPR_TYPE_GET_GLOBAL:
case INIT_EXPR_TYPE_I32_CONST:
case INIT_EXPR_TYPE_I64_CONST:
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
#endif
{
if (!check_global_init_expr(module, init_expr->u.global_index,
error_buf, error_buf_size)) {
WASMValue value;
if (!get_init_value_recursive(module_inst, module, init_expr,
&value, error_buf,
error_buf_size)) {
return false;
}
#if WASM_ENABLE_GC == 0
init_global_data(
p, global->type.val_type,
&module->import_globals[init_expr->u.global_index]
.global_data_linked);
#else
if (init_expr->u.global_index < module->import_global_count) {
init_global_data(
p, global->type.val_type,
&module->import_globals[init_expr->u.global_index]
.global_data_linked);
}
else {
uint32 global_idx =
init_expr->u.global_index - module->import_global_count;
init_global_data(p, global->type.val_type,
&module->globals[global_idx].init_expr.u);
}
#endif
init_global_data(p, global->type.val_type, &value);
break;
}
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
@ -526,7 +610,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
case INIT_EXPR_TYPE_FUNCREF_CONST:
{
WASMFuncObjectRef func_obj = NULL;
uint32 func_idx = init_expr->u.u32;
uint32 func_idx = init_expr->u.unary.v.ref_index;
if (func_idx != UINT32_MAX) {
if (!(func_obj =
@ -541,7 +625,8 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
}
case INIT_EXPR_TYPE_I31_NEW:
{
WASMI31ObjectRef i31_obj = wasm_i31_obj_new(init_expr->u.i32);
WASMI31ObjectRef i31_obj =
wasm_i31_obj_new(init_expr->u.unary.v.i32);
PUT_REF_TO_ADDR(p, i31_obj);
break;
}
@ -555,11 +640,12 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
uint32 type_idx;
if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
init_values = (WASMStructNewInitValues *)init_expr->u.data;
init_values =
(WASMStructNewInitValues *)init_expr->u.unary.v.data;
type_idx = init_values->type_idx;
}
else {
type_idx = init_expr->u.type_index;
type_idx = init_expr->u.unary.v.type_index;
}
struct_type = (WASMStructType *)module->types[type_idx];
@ -609,12 +695,14 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
uint32 type_idx, len;
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
type_idx = init_expr->u.array_new_default.type_index;
len = init_expr->u.array_new_default.length;
type_idx =
init_expr->u.unary.v.array_new_default.type_index;
len = init_expr->u.unary.v.array_new_default.length;
arr_init_val = &empty_val;
}
else {
init_values = (WASMArrayNewInitValues *)init_expr->u.data;
init_values =
(WASMArrayNewInitValues *)init_expr->u.unary.v.data;
type_idx = init_values->type_idx;
len = init_values->length;
@ -660,7 +748,8 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
#endif /* end of WASM_ENABLE_GC != 0 */
default:
{
init_global_data(p, global->type.val_type, &init_expr->u);
init_global_data(p, global->type.val_type,
&init_expr->u.unary.v);
break;
}
}
@ -681,6 +770,7 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
uint64 total_size;
AOTTableInitData *table_seg;
AOTTableInstance *tbl_inst = first_tbl_inst;
uint8 offset_flag;
total_size = (uint64)sizeof(AOTTableInstance *) * module_inst->table_count;
if (total_size > 0
@ -753,28 +843,25 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
tbl_inst = module_inst->tables[table_seg->table_index];
bh_assert(tbl_inst);
offset_flag = table_seg->offset.init_expr_type;
#if WASM_ENABLE_REF_TYPES != 0
bh_assert(
table_seg->offset.init_expr_type
== (tbl_inst->is_table64 ? INIT_EXPR_TYPE_I64_CONST
: INIT_EXPR_TYPE_I32_CONST)
|| table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
|| table_seg->offset.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST
|| table_seg->offset.init_expr_type
== INIT_EXPR_TYPE_REFNULL_CONST);
bh_assert(offset_flag == INIT_EXPR_TYPE_GET_GLOBAL
|| offset_flag == INIT_EXPR_TYPE_FUNCREF_CONST
|| offset_flag == INIT_EXPR_TYPE_REFNULL_CONST
|| (tbl_inst->is_table64 ? is_valid_i64_offset(offset_flag)
: is_valid_i32_offset(offset_flag)));
#else
bh_assert(table_seg->offset.init_expr_type
== (tbl_inst->is_table64 ? INIT_EXPR_TYPE_I64_CONST
: INIT_EXPR_TYPE_I32_CONST)
|| table_seg->offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL);
bh_assert(offset_flag == INIT_EXPR_TYPE_GET_GLOBAL
|| (tbl_inst->is_table64 ? is_valid_i64_offset(offset_flag)
: is_valid_i32_offset(offset_flag)));
#endif
/* Resolve table data base offset */
/* TODO: The table64 current implementation assumes table max size
* UINT32_MAX, so the offset conversion here is safe */
if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
global_index = table_seg->offset.u.global_index;
if (offset_flag == INIT_EXPR_TYPE_GET_GLOBAL) {
global_index = table_seg->offset.u.unary.v.global_index;
if (!check_global_init_expr(module, global_index, error_buf,
error_buf_size)) {
@ -792,8 +879,15 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
base_offset =
*(uint32 *)(module_inst->global_data + global_data_offset);
}
else
base_offset = (uint32)table_seg->offset.u.i32;
else {
WASMValue offset_value;
if (!get_init_value_recursive(module_inst, module,
&table_seg->offset, &offset_value,
error_buf, error_buf_size)) {
return false;
}
base_offset = (uint32)offset_value.i32;
}
/* Copy table data */
/* base_offset only since length might negative */
@ -828,7 +922,7 @@ tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
#if WASM_ENABLE_GC == 0
for (j = 0; j < length; j++) {
tbl_inst->elems[base_offset + j] =
table_seg->init_values[j].u.ref_index;
table_seg->init_values[j].u.unary.v.ref_index;
}
#endif
}
@ -1128,6 +1222,7 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
AOTMemInitData *data_seg;
uint64 total_size;
mem_offset_t base_offset;
uint8 offset_flag;
module_inst->memory_count = memory_count;
total_size = sizeof(AOTMemoryInstance *) * (uint64)memory_count;
@ -1166,15 +1261,15 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
initialized */
continue;
bh_assert(data_seg->offset.init_expr_type
== (memory_inst->is_memory64 ? INIT_EXPR_TYPE_I64_CONST
: INIT_EXPR_TYPE_I32_CONST)
|| data_seg->offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL);
offset_flag = data_seg->offset.init_expr_type;
bh_assert(offset_flag == INIT_EXPR_TYPE_GET_GLOBAL
|| (memory_inst->is_memory64
? is_valid_i64_offset(offset_flag)
: is_valid_i32_offset(offset_flag)));
/* Resolve memory data base offset */
if (data_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
global_index = data_seg->offset.u.global_index;
if (offset_flag == INIT_EXPR_TYPE_GET_GLOBAL) {
global_index = data_seg->offset.u.unary.v.global_index;
if (!check_global_init_expr(module, global_index, error_buf,
error_buf_size)) {
@ -1202,14 +1297,20 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
}
}
else {
WASMValue offset_value;
if (!get_init_value_recursive(module_inst, module,
&data_seg->offset, &offset_value,
error_buf, error_buf_size)) {
return false;
}
#if WASM_ENABLE_MEMORY64 != 0
if (memory_inst->is_memory64) {
base_offset = data_seg->offset.u.i64;
base_offset = offset_value.i64;
}
else
#endif
{
base_offset = data_seg->offset.u.u32;
base_offset = offset_value.u32;
}
}
@ -2055,6 +2156,7 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
uint8 tbl_elem_type;
uint32 tbl_init_size, tbl_max_size, j;
WASMRefType *tbl_elem_ref_type;
WASMValue offset_value;
bh_assert(table_init_data);
@ -2086,69 +2188,73 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
if (!wasm_elem_is_active(table_init_data->mode)) {
continue;
}
bh_assert(table_init_data->offset.init_expr_type
== INIT_EXPR_TYPE_I32_CONST
|| table_init_data->offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL
|| table_init_data->offset.init_expr_type
== INIT_EXPR_TYPE_FUNCREF_CONST
|| table_init_data->offset.init_expr_type
== INIT_EXPR_TYPE_REFNULL_CONST);
uint8 offset_flag = table_init_data->offset.init_expr_type;
bh_assert(offset_flag == INIT_EXPR_TYPE_GET_GLOBAL
|| offset_flag == INIT_EXPR_TYPE_FUNCREF_CONST
|| offset_flag == INIT_EXPR_TYPE_REFNULL_CONST
|| offset_flag == INIT_EXPR_TYPE_I32_CONST
|| offset_flag == INIT_EXPR_TYPE_I32_ADD
|| offset_flag == INIT_EXPR_TYPE_I32_SUB
|| offset_flag == INIT_EXPR_TYPE_I32_MUL);
/* init vec(funcidx) or vec(expr) */
if (table_init_data->offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL) {
if (offset_flag == INIT_EXPR_TYPE_GET_GLOBAL) {
uint32 data_offset;
if (!check_global_init_expr(module,
table_init_data->offset.u.global_index,
error_buf, error_buf_size)) {
if (!check_global_init_expr(
module, table_init_data->offset.u.unary.v.global_index,
error_buf, error_buf_size)) {
goto fail;
}
if (table_init_data->offset.u.global_index
if (table_init_data->offset.u.unary.v.global_index
< module->import_global_count) {
data_offset =
module
->import_globals[table_init_data->offset.u.global_index]
.data_offset;
data_offset = module
->import_globals[table_init_data->offset.u
.unary.v.global_index]
.data_offset;
}
else {
data_offset =
module
->globals[table_init_data->offset.u.global_index
->globals[table_init_data->offset.u.unary.v.global_index
- module->import_global_count]
.data_offset;
}
table_init_data->offset.u.i32 =
offset_value.i32 =
*(uint32 *)(module_inst->global_data + data_offset);
}
else {
if (!get_init_value_recursive(
module_inst, module, &table_init_data->offset,
&offset_value, error_buf, error_buf_size)) {
goto fail;
}
}
/* check offset since length might negative */
if ((uint32)table_init_data->offset.u.i32 > table->cur_size) {
LOG_DEBUG("base_offset(%d) > table->cur_size(%d)",
table_init_data->offset.u.i32, table->cur_size);
if ((uint32)offset_value.i32 > table->cur_size) {
LOG_DEBUG("base_offset(%d) > table->cur_size(%d)", offset_value.i32,
table->cur_size);
set_error_buf(error_buf, error_buf_size,
"out of bounds table access");
goto fail;
}
if ((uint32)table_init_data->offset.u.i32 + table_init_data->value_count
if ((uint32)offset_value.i32 + table_init_data->value_count
> table->cur_size) {
LOG_DEBUG("base_offset(%d) + length(%d) > table->cur_size(%d)",
table_init_data->offset.u.i32,
table_init_data->value_count, table->cur_size);
offset_value.i32, table_init_data->value_count,
table->cur_size);
set_error_buf(error_buf, error_buf_size,
"out of bounds table access");
goto fail;
}
for (j = 0; j < module->table_init_data_list[i]->value_count; j++) {
if (!assign_table_init_value(
module_inst, module, &table_init_data->init_values[j],
table_data + table_init_data->offset.u.i32 + j, error_buf,
error_buf_size)) {
if (!assign_table_init_value(module_inst, module,
&table_init_data->init_values[j],
table_data + offset_value.i32 + j,
error_buf, error_buf_size)) {
goto fail;
}
}
@ -3741,10 +3847,10 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
for (i = 0; i < length; i++) {
#if WASM_ENABLE_GC != 0
/* UINT32_MAX indicates that it is a null ref */
if (init_values[i].u.ref_index != UINT32_MAX) {
if (!(func_obj = aot_create_func_obj(module_inst,
init_values[i].u.ref_index,
true, NULL, 0))) {
if (init_values[i].u.unary.v.ref_index != UINT32_MAX) {
if (!(func_obj = aot_create_func_obj(
module_inst, init_values[i].u.unary.v.ref_index, true,
NULL, 0))) {
aot_set_exception_with_id(module_inst, EXCE_NULL_FUNC_OBJ);
return;
}
@ -3754,7 +3860,7 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
table_elems[i] = NULL_REF;
}
#else
table_elems[i] = init_values[i].u.ref_index;
table_elems[i] = init_values[i].u.unary.v.ref_index;
#endif
}
}

View File

@ -225,3 +225,18 @@ read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
return false;
}
}
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
void
destroy_init_expr_recursive(InitializerExpression *expr)
{
if (expr == NULL) {
return;
}
if (is_expr_binary_op(expr->init_expr_type)) {
destroy_init_expr_recursive(expr->u.binary.l_expr);
destroy_init_expr_recursive(expr->u.binary.r_expr);
}
wasm_runtime_free(expr);
}
#endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */

View File

@ -50,6 +50,11 @@ void
wasm_loader_set_error_buf(char *error_buf, uint32 error_buf_size,
const char *string, bool is_aot);
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
void
destroy_init_expr_recursive(InitializerExpression *expr);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1654,14 +1654,70 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
error_buf_size);
}
static void
instantiation_args_set_defaults(struct InstantiationArgs2 *args)
{
memset(args, 0, sizeof(*args));
}
WASMModuleInstanceCommon *
wasm_runtime_instantiate_ex(WASMModuleCommon *module,
const InstantiationArgs *args, char *error_buf,
uint32 error_buf_size)
{
struct InstantiationArgs2 v2;
instantiation_args_set_defaults(&v2);
v2.v1 = *args;
return wasm_runtime_instantiate_ex2(module, &v2, error_buf, error_buf_size);
}
bool
wasm_runtime_instantiation_args_create(struct InstantiationArgs2 **p)
{
struct InstantiationArgs2 *args = wasm_runtime_malloc(sizeof(*args));
if (args == NULL) {
return false;
}
instantiation_args_set_defaults(args);
*p = args;
return true;
}
void
wasm_runtime_instantiation_args_destroy(struct InstantiationArgs2 *p)
{
wasm_runtime_free(p);
}
void
wasm_runtime_instantiation_args_set_default_stack_size(
struct InstantiationArgs2 *p, uint32 v)
{
p->v1.default_stack_size = v;
}
void
wasm_runtime_instantiation_args_set_host_managed_heap_size(
struct InstantiationArgs2 *p, uint32 v)
{
p->v1.host_managed_heap_size = v;
}
void
wasm_runtime_instantiation_args_set_max_memory_pages(
struct InstantiationArgs2 *p, uint32 v)
{
p->v1.max_memory_pages = v;
}
WASMModuleInstanceCommon *
wasm_runtime_instantiate_ex2(WASMModuleCommon *module,
const struct InstantiationArgs2 *args,
char *error_buf, uint32 error_buf_size)
{
return wasm_runtime_instantiate_internal(
module, NULL, NULL, args->default_stack_size,
args->host_managed_heap_size, args->max_memory_pages, error_buf,
module, NULL, NULL, args->v1.default_stack_size,
args->v1.host_managed_heap_size, args->v1.max_memory_pages, error_buf,
error_buf_size);
}

View File

@ -612,6 +612,10 @@ WASMExecEnv *
wasm_runtime_get_exec_env_tls(void);
#endif
struct InstantiationArgs2 {
InstantiationArgs v1;
};
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_init(void);
@ -700,6 +704,40 @@ wasm_runtime_instantiate_ex(WASMModuleCommon *module,
const InstantiationArgs *args, char *error_buf,
uint32 error_buf_size);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN
bool
wasm_runtime_instantiation_args_create(struct InstantiationArgs2 **p);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN
void
wasm_runtime_instantiation_args_destroy(struct InstantiationArgs2 *p);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN
void
wasm_runtime_instantiation_args_set_default_stack_size(
struct InstantiationArgs2 *p, uint32 v);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN
void
wasm_runtime_instantiation_args_set_host_managed_heap_size(
struct InstantiationArgs2 *p, uint32 v);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN
void
wasm_runtime_instantiation_args_set_max_memory_pages(
struct InstantiationArgs2 *p, uint32 v);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon *
wasm_runtime_instantiate_ex2(WASMModuleCommon *module,
const struct InstantiationArgs2 *args,
char *error_buf, uint32 error_buf_size);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_set_running_mode(wasm_module_inst_t module_inst,

View File

@ -8,7 +8,7 @@
static char aot_error[128];
char *
aot_get_last_error()
aot_get_last_error(void)
{
return aot_error[0] == '\0' ? "" : aot_error;
}

View File

@ -216,7 +216,7 @@ get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data,
#if WASM_ENABLE_GC != 0
WASMModule *module = comp_data->wasm_module;
#endif
bh_assert(expr != NULL);
/* + init value size */
switch (expr->init_expr_type) {
case INIT_EXPR_NONE:
@ -248,7 +248,7 @@ get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data,
{
uint32 i;
WASMStructNewInitValues *struct_new_init_values =
(WASMStructNewInitValues *)expr->u.data;
(WASMStructNewInitValues *)expr->u.unary.v.data;
/* type_index + field_count + fields */
size += sizeof(uint32) + sizeof(uint32);
@ -285,7 +285,7 @@ get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data,
case INIT_EXPR_TYPE_ARRAY_NEW_FIXED:
{
WASMArrayNewInitValues *array_new_init_values =
(WASMArrayNewInitValues *)expr->u.data;
(WASMArrayNewInitValues *)expr->u.unary.v.data;
WASMArrayType *array_type = NULL;
uint32 value_count;
@ -308,6 +308,21 @@ get_init_expr_size(const AOTCompContext *comp_ctx, const AOTCompData *comp_data,
break;
}
#endif /* end of WASM_ENABLE_GC != 0 */
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
{
size +=
get_init_expr_size(comp_ctx, comp_data, expr->u.binary.l_expr);
size +=
get_init_expr_size(comp_ctx, comp_data, expr->u.binary.r_expr);
break;
}
#endif
default:
bh_assert(0);
}
@ -324,15 +339,16 @@ get_table_init_data_size(AOTCompContext *comp_ctx,
/*
* mode (4 bytes), elem_type (4 bytes)
*
* table_index(4 bytes) + init expr type (4 bytes) + init expr value (8
* bytes)
* table_index(4 bytes)
*/
size = (uint32)(sizeof(uint32) * 2 + sizeof(uint32) + sizeof(uint32)
+ sizeof(uint64))
size = (uint32)(sizeof(uint32) * 2 + sizeof(uint32))
/* Size of WasmRefType - inner padding (ref type + nullable +
heap_type) */
+ 8;
size += get_init_expr_size(comp_ctx, comp_ctx->comp_data,
&table_init_data->offset);
/* + value count/func index count (4 bytes) + init_values */
size += sizeof(uint32);
for (i = 0; i < table_init_data->value_count; i++) {
@ -1811,6 +1827,10 @@ static bool
aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
AOTCompContext *comp_ctx, InitializerExpression *expr)
{
if (expr == NULL) {
aot_set_last_error("invalid init expr.");
return false;
}
uint32 offset = *p_offset;
#if WASM_ENABLE_GC != 0
WASMModule *module = comp_ctx->comp_data->wasm_module;
@ -1824,31 +1844,31 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
break;
case INIT_EXPR_TYPE_I32_CONST:
case INIT_EXPR_TYPE_F32_CONST:
EMIT_U32(expr->u.i32);
EMIT_U32(expr->u.unary.v.i32);
break;
case INIT_EXPR_TYPE_I64_CONST:
case INIT_EXPR_TYPE_F64_CONST:
EMIT_U64(expr->u.i64);
EMIT_U64(expr->u.unary.v.i64);
break;
case INIT_EXPR_TYPE_V128_CONST:
EMIT_V128(expr->u.v128);
EMIT_V128(expr->u.unary.v.v128);
break;
case INIT_EXPR_TYPE_GET_GLOBAL:
EMIT_U32(expr->u.global_index);
EMIT_U32(expr->u.unary.v.global_index);
break;
case INIT_EXPR_TYPE_FUNCREF_CONST:
case INIT_EXPR_TYPE_REFNULL_CONST:
EMIT_U32(expr->u.ref_index);
EMIT_U32(expr->u.unary.v.ref_index);
break;
#if WASM_ENABLE_GC != 0
case INIT_EXPR_TYPE_I31_NEW:
EMIT_U32(expr->u.i32);
EMIT_U32(expr->u.unary.v.i32);
break;
case INIT_EXPR_TYPE_STRUCT_NEW:
{
uint32 i;
WASMStructNewInitValues *init_values =
(WASMStructNewInitValues *)expr->u.data;
(WASMStructNewInitValues *)expr->u.unary.v.data;
WASMStructType *struct_type = NULL;
EMIT_U32(init_values->type_idx);
@ -1879,21 +1899,21 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
break;
}
case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
EMIT_U32(expr->u.type_index);
EMIT_U32(expr->u.unary.v.type_index);
break;
case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
{
WASMArrayType *array_type = NULL;
bh_assert(expr->u.array_new_default.type_index
bh_assert(expr->u.unary.v.array_new_default.type_index
< module->type_count);
array_type =
(WASMArrayType *)
module->types[expr->u.array_new_default.type_index];
module->types[expr->u.unary.v.array_new_default.type_index];
EMIT_U32(array_type->elem_type);
EMIT_U32(expr->u.array_new_default.type_index);
EMIT_U32(expr->u.array_new_default.length);
EMIT_U32(expr->u.unary.v.array_new_default.type_index);
EMIT_U32(expr->u.unary.v.array_new_default.length);
break;
}
case INIT_EXPR_TYPE_ARRAY_NEW:
@ -1901,7 +1921,7 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
{
uint32 value_count, i, field_size;
WASMArrayNewInitValues *init_values =
(WASMArrayNewInitValues *)expr->u.data;
(WASMArrayNewInitValues *)expr->u.unary.v.data;
WASMArrayType *array_type = NULL;
bh_assert(init_values->type_idx < module->type_count);
@ -1933,6 +1953,25 @@ aot_emit_init_expr(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
break;
}
#endif /* end of WASM_ENABLE_GC != 0 */
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
if (comp_ctx->enable_extended_const) {
if (!aot_emit_init_expr(buf, buf_end, &offset, comp_ctx,
expr->u.binary.l_expr)) {
return false;
}
if (!aot_emit_init_expr(buf, buf_end, &offset, comp_ctx,
expr->u.binary.r_expr)) {
return false;
}
}
break;
#endif
default:
aot_set_last_error("invalid init expr type.");
return false;
@ -2034,8 +2073,10 @@ aot_emit_table_info(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
EMIT_U32(init_datas[i]->mode);
EMIT_U32(init_datas[i]->elem_type);
EMIT_U32(init_datas[i]->table_index);
EMIT_U32(init_datas[i]->offset.init_expr_type);
EMIT_U64(init_datas[i]->offset.u.i64);
if (!aot_emit_init_expr(buf, buf_end, &offset, comp_ctx,
&init_datas[i]->offset))
return false;
#if WASM_ENABLE_GC != 0
if (comp_ctx->enable_gc && init_datas[i]->elem_ref_type) {
EMIT_U16(init_datas[i]->elem_ref_type->ref_ht_common.ref_type);

View File

@ -2787,6 +2787,9 @@ aot_create_comp_context(const AOTCompData *comp_data, aot_comp_option_t option)
if (option->enable_shared_chain)
comp_ctx->enable_shared_chain = true;
if (option->enable_extended_const)
comp_ctx->enable_extended_const = true;
comp_ctx->opt_level = option->opt_level;
comp_ctx->size_level = option->size_level;

View File

@ -461,6 +461,9 @@ typedef struct AOTCompContext {
/* Enable LLVM PGO (Profile-Guided Optimization) */
bool enable_llvm_pgo;
/* Enable extended constant expression */
bool enable_extended_const;
/* Treat unknown import function as wasm-c-api import function
and allow to directly invoke it from AOT/JIT code */
bool quick_invoke_c_api_import;

View File

@ -121,7 +121,8 @@ wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 seg_idx,
+ dst_offset * sizeof(table_elem_type_t));
init_values = tbl_seg_init_values + src_offset;
for (i = 0; i < len; i++) {
addr[i] = (table_elem_type_t)(uintptr_t)init_values[+i].u.ref_index;
addr[i] =
(table_elem_type_t)(uintptr_t)init_values[+i].u.unary.v.ref_index;
}
return 0;

View File

@ -68,6 +68,7 @@ typedef struct AOTCompOption {
bool enable_ref_types;
bool enable_gc;
bool enable_aux_stack_check;
bool enable_extended_const;
AOTStackFrameType aux_stack_frame_type;
AOTCallStackFeatures call_stack_features;
bool enable_perf_profiling;

View File

@ -98,10 +98,10 @@ void
aot_destroy_aot_file(uint8_t *aot_file);
char *
aot_get_last_error();
aot_get_last_error(void);
uint32_t
aot_get_plt_table_size();
aot_get_plt_table_size(void);
#ifdef __cplusplus
}

View File

@ -289,6 +289,8 @@ typedef struct InstantiationArgs {
} InstantiationArgs;
#endif /* INSTANTIATION_ARGS_OPTION_DEFINED */
struct InstantiationArgs2;
#ifndef WASM_VALKIND_T_DEFINED
#define WASM_VALKIND_T_DEFINED
typedef uint8_t wasm_valkind_t;
@ -733,6 +735,46 @@ wasm_runtime_instantiate_ex(const wasm_module_t module,
const InstantiationArgs *args, char *error_buf,
uint32_t error_buf_size);
/**
* Create an InstantiationArgs2 object with default parameters.
*
* @return true if success, false otherwise
*/
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_instantiation_args_create(struct InstantiationArgs2 **p);
/**
* Dispose an InstantiationArgs2 object.
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_instantiation_args_destroy(struct InstantiationArgs2 *p);
/**
* Setter functions for the InstantiationArgs2 object.
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_instantiation_args_set_default_stack_size(
struct InstantiationArgs2 *p, uint32_t v);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_instantiation_args_set_host_managed_heap_size(
struct InstantiationArgs2 *p, uint32_t v);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_instantiation_args_set_max_memory_pages(
struct InstantiationArgs2 *p, uint32_t v);
/**
* Instantiate a WASM module, with specified instantiation arguments
*
* Same as wasm_runtime_instantiate_ex, but this version takes
* InstantiationArgs2, which can be extended without breaking the ABI.
*/
WASM_RUNTIME_API_EXTERN wasm_module_inst_t
wasm_runtime_instantiate_ex2(const wasm_module_t module,
const struct InstantiationArgs2 *args,
char *error_buf, uint32_t error_buf_size);
/**
* Set the running mode of a WASM module instance, override the
* default running mode of the runtime. Note that it only makes sense when

View File

@ -135,6 +135,12 @@ typedef void *table_elem_type_t;
#define INIT_EXPR_TYPE_F64_CONST 0x44
#define INIT_EXPR_TYPE_V128_CONST 0xFD
#define INIT_EXPR_TYPE_GET_GLOBAL 0x23
#define INIT_EXPR_TYPE_I32_ADD 0x6A
#define INIT_EXPR_TYPE_I32_SUB 0x6B
#define INIT_EXPR_TYPE_I32_MUL 0x6C
#define INIT_EXPR_TYPE_I64_ADD 0x7C
#define INIT_EXPR_TYPE_I64_SUB 0x7D
#define INIT_EXPR_TYPE_I64_MUL 0x7E
#define INIT_EXPR_TYPE_REFNULL_CONST 0xD0
#define INIT_EXPR_TYPE_FUNCREF_CONST 0xD2
#define INIT_EXPR_TYPE_STRUCT_NEW 0xD3
@ -277,9 +283,41 @@ typedef struct InitializerExpression {
/* type of INIT_EXPR_TYPE_XXX, which is an instruction of
constant expression */
uint8 init_expr_type;
WASMValue u;
union {
struct {
WASMValue v;
} unary;
struct {
struct InitializerExpression *l_expr;
struct InitializerExpression *r_expr;
} binary;
} u;
} InitializerExpression;
static inline bool
is_expr_binary_op(uint8 flag)
{
return flag == INIT_EXPR_TYPE_I32_ADD || flag == INIT_EXPR_TYPE_I32_SUB
|| flag == INIT_EXPR_TYPE_I32_MUL || flag == INIT_EXPR_TYPE_I64_ADD
|| flag == INIT_EXPR_TYPE_I64_SUB || flag == INIT_EXPR_TYPE_I64_MUL;
}
/* check if table or data offset is valid for i32 offset */
static inline bool
is_valid_i32_offset(uint8 flag)
{
return flag == INIT_EXPR_TYPE_I32_CONST || flag == INIT_EXPR_TYPE_I32_ADD
|| flag == INIT_EXPR_TYPE_I32_SUB || flag == INIT_EXPR_TYPE_I32_MUL;
}
/* check if table or data offset is valid for i64 offset */
static inline bool
is_valid_i64_offset(uint8 flag)
{
return flag == INIT_EXPR_TYPE_I64_CONST || flag == INIT_EXPR_TYPE_I64_ADD
|| flag == INIT_EXPR_TYPE_I64_SUB || flag == INIT_EXPR_TYPE_I64_MUL;
}
#if WASM_ENABLE_GC != 0
/**
* Reference type of (ref null ht) or (ref ht),

View File

@ -5958,12 +5958,14 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|| init_values[i].init_expr_type
== INIT_EXPR_TYPE_FUNCREF_CONST);
#if WASM_ENABLE_GC == 0
table_elems[i] =
(table_elem_type_t)init_values[i].u.ref_index;
table_elems[i] = (table_elem_type_t)init_values[i]
.u.unary.v.ref_index;
#else
if (init_values[i].u.ref_index != UINT32_MAX) {
if (init_values[i].u.unary.v.ref_index
!= UINT32_MAX) {
if (!(func_obj = wasm_create_func_obj(
module, init_values[i].u.ref_index,
module,
init_values[i].u.unary.v.ref_index,
true, NULL, 0))) {
goto got_exception;
}

View File

@ -5350,12 +5350,14 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|| init_values[i].init_expr_type
== INIT_EXPR_TYPE_FUNCREF_CONST);
#if WASM_ENABLE_GC == 0
table_elems[i] =
(table_elem_type_t)init_values[i].u.ref_index;
table_elems[i] = (table_elem_type_t)init_values[i]
.u.unary.v.ref_index;
#else
if (init_values[i].u.ref_index != UINT32_MAX) {
if (init_values[i].u.unary.v.ref_index
!= UINT32_MAX) {
if (!(func_obj = wasm_create_func_obj(
module, init_values[i].u.ref_index,
module,
init_values[i].u.unary.v.ref_index,
true, NULL, 0))) {
goto got_exception;
}

View File

@ -400,7 +400,8 @@ check_array_type(const WASMModule *module, uint32 type_index, char *error_buf,
error_buf_size)) {
return false;
}
if (module->types[type_index]->type_flag != WASM_TYPE_ARRAY) {
if (module->types[type_index] == NULL
|| module->types[type_index]->type_flag != WASM_TYPE_ARRAY) {
set_error_buf(error_buf, error_buf_size, "unknown array type");
return false;
}
@ -423,7 +424,8 @@ check_function_type(const WASMModule *module, uint32 type_index,
}
#if WASM_ENABLE_GC != 0
if (module->types[type_index]->type_flag != WASM_TYPE_FUNC) {
if (module->types[type_index] == NULL
|| module->types[type_index]->type_flag != WASM_TYPE_FUNC) {
set_error_buf(error_buf, error_buf_size, "unknown function type");
return false;
}
@ -453,6 +455,9 @@ typedef struct InitValue {
WASMRefType ref_type;
#endif
WASMValue value;
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
InitializerExpression *expr;
#endif
} InitValue;
typedef struct ConstExprContext {
@ -477,7 +482,11 @@ push_const_expr_stack(ConstExprContext *ctx, uint8 flag, uint8 type,
#if WASM_ENABLE_GC != 0
WASMRefType *ref_type, uint8 gc_opcode,
#endif
WASMValue *value, char *error_buf, uint32 error_buf_size)
WASMValue *value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
InitializerExpression *expr,
#endif
char *error_buf, uint32 error_buf_size)
{
InitValue *cur_value;
@ -503,6 +512,10 @@ push_const_expr_stack(ConstExprContext *ctx, uint8 flag, uint8 type,
cur_value->flag = flag;
cur_value->value = *value;
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
cur_value->expr = expr;
#endif
#if WASM_ENABLE_GC != 0
cur_value->gc_opcode = gc_opcode;
if (wasm_is_type_multi_byte_type(type)) {
@ -587,7 +600,11 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
#if WASM_ENABLE_GC != 0
WASMRefType *ref_type, uint8 *p_gc_opcode,
#endif
WASMValue *p_value, char *error_buf, uint32 error_buf_size)
WASMValue *p_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
InitializerExpression **p_expr,
#endif
char *error_buf, uint32 error_buf_size)
{
InitValue *cur_value;
@ -623,7 +640,10 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
if (p_gc_opcode)
*p_gc_opcode = cur_value->gc_opcode;
#endif
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
if (p_expr)
*p_expr = cur_value->expr;
#endif
return true;
#if WASM_ENABLE_GC != 0
@ -639,7 +659,7 @@ fail:
}
static void
destroy_const_expr_stack(ConstExprContext *ctx)
destroy_const_expr_stack(ConstExprContext *ctx, bool free_exprs)
{
#if WASM_ENABLE_GC != 0
uint32 i;
@ -654,24 +674,62 @@ destroy_const_expr_stack(ConstExprContext *ctx)
}
}
#endif
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
if (free_exprs) {
for (uint32 j = 0; j < ctx->sp; j++) {
if (is_expr_binary_op(ctx->stack[j].expr->init_expr_type)) {
destroy_init_expr_recursive(ctx->stack[j].expr);
ctx->stack[j].expr = NULL;
}
}
}
#endif
if (ctx->stack != ctx->data) {
wasm_runtime_free(ctx->stack);
}
}
#if WASM_ENABLE_GC != 0
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
static void
destroy_init_expr(WASMModule *module, InitializerExpression *expr)
{
#if WASM_ENABLE_GC != 0
if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
|| expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
destroy_init_expr_data_recursive(module, expr->u.data);
destroy_init_expr_data_recursive(module, expr->u.unary.v.data);
}
}
#endif /* end of WASM_ENABLE_GC != 0 */
#endif
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
// free left expr and right exprs for binary oprand
if (!is_expr_binary_op(expr->init_expr_type)) {
return;
}
if (expr->u.binary.l_expr) {
destroy_init_expr_recursive(expr->u.binary.l_expr);
}
if (expr->u.binary.r_expr) {
destroy_init_expr_recursive(expr->u.binary.r_expr);
}
expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
#endif
}
#endif
/* for init expr
* (data (i32.add (i32.const 0) (i32.sub (i32.const 1) (i32.const 2)))),
* the binary format is
* 0x11: 41 00 ; i32.const 0
* 0x13: 41 01 ; i32.const 1
* 0x15: 41 02 ; i32.const 2
* 0x17: 6b ; i32.sub
* 0x18: 6a ; i32.add
* for traversal: read opcodes and push them onto the stack. When encountering
* a binary opcode, pop two values from the stack which become the left and
* right child nodes of this binary operation node.
*/
static bool
load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
InitializerExpression *init_expr, uint8 type, void *ref_type,
@ -687,6 +745,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
uint8 opcode;
WASMRefType cur_ref_type = { 0 };
#endif
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
InitializerExpression *cur_expr = NULL;
#endif
init_const_expr_stack(&const_expr_ctx, module);
@ -699,24 +760,32 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
case INIT_EXPR_TYPE_I32_CONST:
read_leb_int32(p, p_end, cur_value.i32);
if (!push_const_expr_stack(
&const_expr_ctx, flag, VALUE_TYPE_I32,
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_I32,
#if WASM_ENABLE_GC != 0
NULL, 0,
NULL, 0,
#endif
&cur_value, error_buf, error_buf_size))
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
break;
/* i64.const */
case INIT_EXPR_TYPE_I64_CONST:
read_leb_int64(p, p_end, cur_value.i64);
if (!push_const_expr_stack(
&const_expr_ctx, flag, VALUE_TYPE_I64,
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_I64,
#if WASM_ENABLE_GC != 0
NULL, 0,
NULL, 0,
#endif
&cur_value, error_buf, error_buf_size))
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
break;
/* f32.const */
@ -726,12 +795,16 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
for (i = 0; i < sizeof(float32); i++)
*p_float++ = *p++;
if (!push_const_expr_stack(
&const_expr_ctx, flag, VALUE_TYPE_F32,
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_F32,
#if WASM_ENABLE_GC != 0
NULL, 0,
NULL, 0,
#endif
&cur_value, error_buf, error_buf_size))
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
break;
/* f64.const */
@ -741,12 +814,16 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
for (i = 0; i < sizeof(float64); i++)
*p_float++ = *p++;
if (!push_const_expr_stack(
&const_expr_ctx, flag, VALUE_TYPE_F64,
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_F64,
#if WASM_ENABLE_GC != 0
NULL, 0,
NULL, 0,
#endif
&cur_value, error_buf, error_buf_size))
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
break;
#if WASM_ENABLE_SIMD != 0
@ -767,12 +844,16 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
cur_value.v128.i64x2[0] = high;
cur_value.v128.i64x2[1] = low;
if (!push_const_expr_stack(
&const_expr_ctx, flag, VALUE_TYPE_V128,
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_V128,
#if WASM_ENABLE_GC != 0
NULL, 0,
NULL, 0,
#endif
&cur_value, error_buf, error_buf_size))
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
#if WASM_ENABLE_WAMR_COMPILER != 0
/* If any init_expr is v128.const, mark SIMD used */
@ -783,7 +864,92 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
#endif /* end of (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) || \
(WASM_ENABLE_FAST_INTERP != 0) */
#endif /* end of WASM_ENABLE_SIMD */
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
{
InitializerExpression *l_expr, *r_expr;
WASMValue l_value, r_value;
uint8 l_flag, r_flag;
uint8 value_type;
if (flag == INIT_EXPR_TYPE_I32_ADD
|| flag == INIT_EXPR_TYPE_I32_SUB
|| flag == INIT_EXPR_TYPE_I32_MUL) {
value_type = VALUE_TYPE_I32;
}
else {
value_type = VALUE_TYPE_I64;
}
/* If right flag indicates a binary operation, right expr will
* be popped from stack. Otherwise, allocate a new expr for
* right expr. Same for left expr.
*/
if (!(pop_const_expr_stack(&const_expr_ctx, &r_flag, value_type,
#if WASM_ENABLE_GC != 0
NULL, NULL,
#endif
&r_value, &r_expr, error_buf,
error_buf_size))) {
goto fail;
}
if (!is_expr_binary_op(r_flag)) {
if (!(r_expr = loader_malloc(sizeof(InitializerExpression),
error_buf, error_buf_size))) {
goto fail;
}
r_expr->init_expr_type = r_flag;
r_expr->u.unary.v = r_value;
}
if (!(pop_const_expr_stack(&const_expr_ctx, &l_flag, value_type,
#if WASM_ENABLE_GC != 0
NULL, NULL,
#endif
&l_value, &l_expr, error_buf,
error_buf_size))) {
destroy_init_expr_recursive(r_expr);
goto fail;
}
if (!is_expr_binary_op(l_flag)) {
if (!(l_expr = loader_malloc(sizeof(InitializerExpression),
error_buf, error_buf_size))) {
destroy_init_expr_recursive(r_expr);
goto fail;
}
l_expr->init_expr_type = l_flag;
l_expr->u.unary.v = l_value;
}
if (!(cur_expr = loader_malloc(sizeof(InitializerExpression),
error_buf, error_buf_size))) {
destroy_init_expr_recursive(l_expr);
destroy_init_expr_recursive(r_expr);
goto fail;
}
cur_expr->init_expr_type = flag;
cur_expr->u.binary.l_expr = l_expr;
cur_expr->u.binary.r_expr = r_expr;
if (!push_const_expr_stack(&const_expr_ctx, flag, value_type,
#if WASM_ENABLE_GC != 0
NULL, 0,
#endif
&cur_value, cur_expr, error_buf,
error_buf_size)) {
destroy_init_expr_recursive(cur_expr);
goto fail;
}
break;
}
#endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR */
#if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
/* ref.func */
case INIT_EXPR_TYPE_FUNCREF_CONST:
@ -799,6 +965,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
#if WASM_ENABLE_GC == 0
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_FUNCREF, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
#else
@ -816,8 +985,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
false, type_idx);
if (!push_const_expr_stack(&const_expr_ctx, flag,
cur_ref_type.ref_type, &cur_ref_type,
0, &cur_value, error_buf,
error_buf_size))
0, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
#endif
#if WASM_ENABLE_WAMR_COMPILER != 0
@ -829,45 +1001,71 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
/* ref.null */
case INIT_EXPR_TYPE_REFNULL_CONST:
{
uint8 type1;
#if WASM_ENABLE_GC == 0
uint8 type1;
CHECK_BUF(p, p_end, 1);
type1 = read_uint8(p);
cur_value.ref_index = NULL_REF;
if (!push_const_expr_stack(&const_expr_ctx, flag, type1,
&cur_value, error_buf,
error_buf_size))
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
#else
/*
* According to the current GC SPEC rules, the heap_type must be
* validated when ref.null is used. It can be an absheaptype,
* or the type C.types[type_idx] must be defined in the context.
*/
int32 heap_type;
read_leb_int32(p, p_end, heap_type);
type1 = (uint8)((int32)0x80 + heap_type);
cur_value.gc_obj = NULL_REF;
if (!is_byte_a_type(type1)
|| !wasm_is_valid_heap_type(heap_type)
|| wasm_is_type_multi_byte_type(type1)) {
p--;
read_leb_uint32(p, p_end, type_idx);
if (!check_type_index(module, module->type_count, type_idx,
error_buf, error_buf_size))
goto fail;
/*
* The current check of heap_type can deterministically infer
* the result of the previous condition
* `(!is_byte_a_type(type1) ||
* wasm_is_type_multi_byte_type(type1))`. Therefore, the
* original condition is redundant and has been removed.
*
* This logic is consistent with the implementation of the
* `WASM_OP_REF_NULL` case in the `wasm_loader_prepare_bytecode`
* function.
*/
if (heap_type >= 0) {
if (!check_type_index(module, module->type_count, heap_type,
error_buf, error_buf_size)) {
goto fail;
}
wasm_set_refheaptype_typeidx(&cur_ref_type.ref_ht_typeidx,
true, type_idx);
true, heap_type);
if (!push_const_expr_stack(&const_expr_ctx, flag,
cur_ref_type.ref_type,
&cur_ref_type, 0, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
}
else {
if (!push_const_expr_stack(&const_expr_ctx, flag, type1,
NULL, 0, &cur_value, error_buf,
error_buf_size))
if (!wasm_is_valid_heap_type(heap_type)) {
set_error_buf_v(error_buf, error_buf_size,
"unknown type %d", heap_type);
goto fail;
}
cur_ref_type.ref_ht_common.ref_type =
(uint8)((int32)0x80 + heap_type);
if (!push_const_expr_stack(&const_expr_ctx, flag,
cur_ref_type.ref_type, NULL, 0,
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
}
#endif
@ -956,8 +1154,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
#if WASM_ENABLE_GC != 0
&cur_ref_type, 0,
#endif
&cur_value, error_buf,
error_buf_size))
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
break;
@ -1020,6 +1221,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
&const_expr_ctx, NULL, field_type,
field_ref_type, NULL,
&struct_init_values->fields[field_idx],
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
destroy_init_expr_data_recursive(
module, struct_init_values);
@ -1033,6 +1237,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!push_const_expr_stack(
&const_expr_ctx, flag, cur_ref_type.ref_type,
&cur_ref_type, (uint8)opcode1, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
destroy_init_expr_data_recursive(
module, struct_init_values);
@ -1050,8 +1257,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
error_buf_size)) {
goto fail;
}
if (module->types[type_idx]->type_flag
!= WASM_TYPE_STRUCT) {
if (module->types[type_idx] == NULL
|| module->types[type_idx]->type_flag
!= WASM_TYPE_STRUCT) {
set_error_buf(error_buf, error_buf_size,
"unknown struct type");
goto fail;
@ -1064,6 +1272,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!push_const_expr_stack(
&const_expr_ctx, flag, cur_ref_type.ref_type,
&cur_ref_type, (uint8)opcode1, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
goto fail;
}
@ -1112,8 +1323,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!pop_const_expr_stack(
&const_expr_ctx, NULL, VALUE_TYPE_I32,
NULL, NULL, &len_val, error_buf,
error_buf_size)) {
NULL, NULL, &len_val,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
goto fail;
}
@ -1132,6 +1346,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
&const_expr_ctx, NULL, elem_type,
elem_ref_type, NULL,
&array_init_values->elem_data[0],
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
destroy_init_expr_data_recursive(
module, array_init_values);
@ -1164,6 +1381,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
elem_ref_type, NULL,
&array_init_values
->elem_data[i - 1],
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
destroy_init_expr_data_recursive(
module, array_init_values);
@ -1180,10 +1400,13 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
uint32 len;
/* POP(i32) */
if (!pop_const_expr_stack(&const_expr_ctx, NULL,
VALUE_TYPE_I32, NULL,
NULL, &len_val, error_buf,
error_buf_size)) {
if (!pop_const_expr_stack(
&const_expr_ctx, NULL, VALUE_TYPE_I32, NULL,
NULL, &len_val,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
goto fail;
}
len = len_val.i32;
@ -1197,6 +1420,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!push_const_expr_stack(
&const_expr_ctx, flag, cur_ref_type.ref_type,
&cur_ref_type, (uint8)opcode1, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
if (array_init_values) {
destroy_init_expr_data_recursive(
@ -1223,9 +1449,13 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
case WASM_OP_REF_I31:
{
/* POP(i32) */
if (!pop_const_expr_stack(
&const_expr_ctx, NULL, VALUE_TYPE_I32, NULL,
NULL, &cur_value, error_buf, error_buf_size)) {
if (!pop_const_expr_stack(&const_expr_ctx, NULL,
VALUE_TYPE_I32, NULL, NULL,
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
goto fail;
}
@ -1234,6 +1464,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!push_const_expr_stack(
&const_expr_ctx, flag, cur_ref_type.ref_type,
&cur_ref_type, (uint8)opcode1, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
goto fail;
}
@ -1268,7 +1501,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
#if WASM_ENABLE_GC != 0
ref_type, &opcode,
#endif
&cur_value, error_buf, error_buf_size)) {
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
&cur_expr,
#endif
error_buf, error_buf_size)) {
goto fail;
}
@ -1278,8 +1515,21 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
goto fail;
}
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
if (cur_expr != NULL) {
bh_memcpy_s(init_expr, sizeof(InitializerExpression), cur_expr,
sizeof(InitializerExpression));
wasm_runtime_free(cur_expr);
}
else {
init_expr->init_expr_type = flag;
init_expr->u.unary.v = cur_value;
}
#else
init_expr->init_expr_type = flag;
init_expr->u = cur_value;
init_expr->u.unary.v = cur_value;
#endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */
#if WASM_ENABLE_GC != 0
if (init_expr->init_expr_type == WASM_OP_GC_PREFIX) {
@ -1310,11 +1560,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
#endif /* end of WASM_ENABLE_GC != 0 */
*p_buf = p;
destroy_const_expr_stack(&const_expr_ctx);
destroy_const_expr_stack(&const_expr_ctx, false);
return true;
fail:
destroy_const_expr_stack(&const_expr_ctx);
destroy_const_expr_stack(&const_expr_ctx, true);
return false;
}
@ -2056,9 +2306,14 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
total_size = new_total_size;
}
LOG_VERBOSE("Processing rec group [%d-%d]",
processed_type_count,
processed_type_count + rec_count - 1);
if (rec_count < 1) {
LOG_VERBOSE("Processing 0-entry rec group");
}
else {
LOG_VERBOSE("Processing rec group [%d-%d]",
processed_type_count,
processed_type_count + rec_count - 1);
}
}
else {
p--;
@ -4072,9 +4327,9 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
if (global->init_expr.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
uint8 global_type;
WASMRefType *global_ref_type;
uint32 global_idx = global->init_expr.u.global_index;
uint32 global_idx = global->init_expr.u.unary.v.global_index;
if (global->init_expr.u.global_index
if (global->init_expr.u.unary.v.global_index
>= module->import_global_count + i) {
set_error_buf(error_buf, error_buf_size, "unknown global");
return false;
@ -4471,7 +4726,7 @@ load_func_index_vec(const uint8 **p_buf, const uint8 *buf_end,
}
init_expr->init_expr_type = INIT_EXPR_TYPE_FUNCREF_CONST;
init_expr->u.ref_index = function_index;
init_expr->u.unary.v.ref_index = function_index;
}
*p_buf = p;
@ -4744,7 +4999,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
#if WASM_ENABLE_MEMORY64 != 0
if (table_elem_idx_type == VALUE_TYPE_I64
&& table_segment->base_offset.u.u64 > UINT32_MAX) {
&& table_segment->base_offset.u.unary.v.u64 > UINT32_MAX) {
set_error_buf(error_buf, error_buf_size,
"In table64, table base offset can't be "
"larger than UINT32_MAX");
@ -4904,6 +5159,9 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
if (!(dataseg = module->data_segments[i] = loader_malloc(
sizeof(WASMDataSeg), error_buf, error_buf_size))) {
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
destroy_init_expr(module, &init_expr);
#endif
return false;
}
@ -6031,7 +6289,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
&& global->init_expr.init_expr_type
== INIT_EXPR_TYPE_I32_CONST) {
aux_heap_base_global = global;
aux_heap_base = (uint64)(uint32)global->init_expr.u.i32;
aux_heap_base =
(uint64)(uint32)global->init_expr.u.unary.v.i32;
aux_heap_base_global_index = export->index;
LOG_VERBOSE("Found aux __heap_base global, value: %" PRIu64,
aux_heap_base);
@ -6052,7 +6311,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
&& global->init_expr.init_expr_type
== INIT_EXPR_TYPE_I32_CONST) {
aux_data_end_global = global;
aux_data_end = (uint64)(uint32)global->init_expr.u.i32;
aux_data_end =
(uint64)(uint32)global->init_expr.u.unary.v.i32;
aux_data_end_global_index = export->index;
LOG_VERBOSE("Found aux __data_end global, value: %" PRIu64,
aux_data_end);
@ -6093,10 +6353,11 @@ load_from_sections(WASMModule *module, WASMSection *sections,
&& global->type.val_type == VALUE_TYPE_I32
&& global->init_expr.init_expr_type
== INIT_EXPR_TYPE_I32_CONST
&& (uint64)(uint32)global->init_expr.u.i32
&& (uint64)(uint32)global->init_expr.u.unary.v.i32
<= aux_heap_base) {
aux_stack_top_global = global;
aux_stack_top = (uint64)(uint32)global->init_expr.u.i32;
aux_stack_top =
(uint64)(uint32)global->init_expr.u.unary.v.i32;
module->aux_stack_top_global_index =
module->import_global_count + global_index;
module->aux_stack_bottom = aux_stack_top;
@ -6947,7 +7208,7 @@ wasm_loader_unload(WASMModule *module)
wasm_runtime_free(module->memories);
if (module->globals) {
#if WASM_ENABLE_GC != 0
#if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
for (i = 0; i < module->global_count; i++) {
destroy_init_expr(module, &module->globals[i].init_expr);
}
@ -6980,6 +7241,9 @@ wasm_loader_unload(WASMModule *module)
#endif
wasm_runtime_free(module->table_segments[i].init_values);
}
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
destroy_init_expr(module, &module->table_segments[i].base_offset);
#endif
}
wasm_runtime_free(module->table_segments);
}
@ -6989,6 +7253,10 @@ wasm_loader_unload(WASMModule *module)
if (module->data_segments[i]) {
if (module->data_segments[i]->is_data_cloned)
wasm_runtime_free(module->data_segments[i]->data);
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
destroy_init_expr(module,
&(module->data_segments[i]->base_offset));
#endif
wasm_runtime_free(module->data_segments[i]);
}
}
@ -12417,7 +12685,9 @@ re_scan:
error_buf, error_buf_size)) {
goto fail;
}
if (module->types[type_idx1]->type_flag != WASM_TYPE_FUNC) {
if (module->types[type_idx1] == NULL
|| module->types[type_idx1]->type_flag
!= WASM_TYPE_FUNC) {
set_error_buf(error_buf, error_buf_size,
"unknown function type");
goto fail;
@ -12434,7 +12704,9 @@ re_scan:
error_buf, error_buf_size)) {
goto fail;
}
if (module->types[type_idx]->type_flag != WASM_TYPE_FUNC) {
if (module->types[type_idx] == NULL
|| module->types[type_idx]->type_flag
!= WASM_TYPE_FUNC) {
set_error_buf(error_buf, error_buf_size,
"unknown function type");
goto fail;
@ -13260,7 +13532,8 @@ re_scan:
== VALUE_TYPE_FUNCREF
&& module->globals[i].init_expr.init_expr_type
== INIT_EXPR_TYPE_FUNCREF_CONST
&& module->globals[i].init_expr.u.u32 == func_idx) {
&& module->globals[i].init_expr.u.unary.v.u32
== func_idx) {
func_declared = true;
break;
}
@ -13289,7 +13562,8 @@ re_scan:
#endif
) {
for (j = 0; j < table_seg->value_count; j++) {
if (table_seg->init_values[j].u.ref_index
if (table_seg->init_values[j]
.u.unary.v.ref_index
== func_idx) {
func_declared = true;
break;
@ -14271,8 +14545,9 @@ re_scan:
error_buf_size)) {
goto fail;
}
if (module->types[type_idx]->type_flag
!= WASM_TYPE_STRUCT) {
if (module->types[type_idx] == NULL
|| module->types[type_idx]->type_flag
!= WASM_TYPE_STRUCT) {
set_error_buf(error_buf, error_buf_size,
"unknown struct type");
goto fail;
@ -14358,8 +14633,9 @@ re_scan:
error_buf_size)) {
goto fail;
}
if (module->types[type_idx]->type_flag
!= WASM_TYPE_STRUCT) {
if (module->types[type_idx] == NULL
|| module->types[type_idx]->type_flag
!= WASM_TYPE_STRUCT) {
set_error_buf(error_buf, error_buf_size,
"unknown struct type");
goto fail;

View File

@ -261,6 +261,9 @@ typedef struct InitValue {
uint8 type;
uint8 flag;
WASMValue value;
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
InitializerExpression *expr;
#endif
} InitValue;
typedef struct ConstExprContext {
@ -282,7 +285,11 @@ init_const_expr_stack(ConstExprContext *ctx, WASMModule *module)
static bool
push_const_expr_stack(ConstExprContext *ctx, uint8 flag, uint8 type,
WASMValue *value, char *error_buf, uint32 error_buf_size)
WASMValue *value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
InitializerExpression *expr,
#endif
char *error_buf, uint32 error_buf_size)
{
InitValue *cur_value;
@ -305,6 +312,9 @@ push_const_expr_stack(ConstExprContext *ctx, uint8 flag, uint8 type,
cur_value->type = type;
cur_value->flag = flag;
cur_value->value = *value;
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
cur_value->expr = expr;
#endif
return true;
fail:
@ -313,7 +323,11 @@ fail:
static bool
pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
WASMValue *p_value, char *error_buf, uint32 error_buf_size)
WASMValue *p_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
InitializerExpression **p_expr,
#endif
char *error_buf, uint32 error_buf_size)
{
InitValue *cur_value;
@ -331,18 +345,50 @@ pop_const_expr_stack(ConstExprContext *ctx, uint8 *p_flag, uint8 type,
*p_flag = cur_value->flag;
if (p_value)
*p_value = cur_value->value;
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
if (p_expr)
*p_expr = cur_value->expr;
#endif
return true;
}
static void
destroy_const_expr_stack(ConstExprContext *ctx)
destroy_const_expr_stack(ConstExprContext *ctx, bool free_exprs)
{
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
if (free_exprs) {
for (uint32 j = 0; j < ctx->sp; j++) {
if (is_expr_binary_op(ctx->stack[j].expr->init_expr_type)) {
destroy_init_expr_recursive(ctx->stack[j].expr);
ctx->stack[j].expr = NULL;
}
}
}
#endif
if (ctx->stack != ctx->data) {
wasm_runtime_free(ctx->stack);
}
}
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
static void
destroy_init_expr(InitializerExpression *expr)
{
// free left expr and right exprs for binary oprand
if (is_expr_binary_op(expr->init_expr_type)) {
return;
}
if (expr->u.binary.l_expr) {
destroy_init_expr_recursive(expr->u.binary.l_expr);
}
if (expr->u.binary.r_expr) {
destroy_init_expr_recursive(expr->u.binary.r_expr);
}
expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
}
#endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */
static bool
load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
InitializerExpression *init_expr, uint8 type, char *error_buf,
@ -353,6 +399,9 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
uint32 i;
ConstExprContext const_expr_ctx = { 0 };
WASMValue cur_value = { 0 };
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
InitializerExpression *cur_expr = NULL;
#endif
init_const_expr_stack(&const_expr_ctx, module);
@ -367,8 +416,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_I32, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
bh_assert(0);
goto fail;
}
break;
/* i64.const */
@ -377,8 +429,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_I64, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
bh_assert(0);
goto fail;
}
break;
/* f32.const */
@ -390,8 +445,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_F32, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
bh_assert(0);
goto fail;
}
break;
/* f64.const */
@ -403,8 +461,11 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_F64, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
bh_assert(0);
goto fail;
}
break;
@ -417,13 +478,16 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
cur_value.ref_index = func_idx;
if (!check_function_index(module, func_idx, error_buf,
error_buf_size)) {
bh_assert(0);
goto fail;
}
if (!push_const_expr_stack(&const_expr_ctx, flag,
VALUE_TYPE_FUNCREF, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
bh_assert(0);
goto fail;
}
break;
}
@ -438,9 +502,12 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
cur_value.ref_index = UINT32_MAX;
if (!push_const_expr_stack(&const_expr_ctx, flag, type1,
&cur_value, error_buf,
error_buf_size)) {
bh_assert(0);
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size)) {
goto fail;
}
break;
}
@ -471,15 +538,93 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
}
if (!push_const_expr_stack(&const_expr_ctx, flag, global_type,
&cur_value, error_buf,
error_buf_size))
bh_assert(0);
&cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
NULL,
#endif
error_buf, error_buf_size))
goto fail;
break;
}
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_MUL:
{
InitializerExpression *l_expr, *r_expr;
WASMValue l_value, r_value;
uint8 l_flag, r_flag;
uint8 value_type;
if (flag == INIT_EXPR_TYPE_I32_ADD
|| flag == INIT_EXPR_TYPE_I32_SUB
|| flag == INIT_EXPR_TYPE_I32_MUL) {
value_type = VALUE_TYPE_I32;
}
else {
value_type = VALUE_TYPE_I64;
}
/* If right flag indicates a binary operation, right expr will
* be popped from stack. Otherwise, allocate a new expr for
* right expr. Same for left expr.
*/
if (!(pop_const_expr_stack(&const_expr_ctx, &r_flag, value_type,
&r_value, &r_expr, error_buf,
error_buf_size))) {
goto fail;
}
if (!is_expr_binary_op(r_flag)) {
if (!(r_expr = loader_malloc(sizeof(InitializerExpression),
error_buf, error_buf_size))) {
goto fail;
}
r_expr->init_expr_type = r_flag;
r_expr->u.unary.v = r_value;
}
if (!(pop_const_expr_stack(&const_expr_ctx, &l_flag, value_type,
&l_value, &l_expr, error_buf,
error_buf_size))) {
destroy_init_expr_recursive(r_expr);
goto fail;
}
if (!is_expr_binary_op(l_flag)) {
if (!(l_expr = loader_malloc(sizeof(InitializerExpression),
error_buf, error_buf_size))) {
destroy_init_expr_recursive(r_expr);
goto fail;
}
l_expr->init_expr_type = l_flag;
l_expr->u.unary.v = l_value;
}
if (!(cur_expr = loader_malloc(sizeof(InitializerExpression),
error_buf, error_buf_size))) {
destroy_init_expr_recursive(l_expr);
destroy_init_expr_recursive(r_expr);
goto fail;
}
cur_expr->init_expr_type = flag;
cur_expr->u.binary.l_expr = l_expr;
cur_expr->u.binary.r_expr = r_expr;
if (!push_const_expr_stack(&const_expr_ctx, flag, value_type,
&cur_value, cur_expr, error_buf,
error_buf_size)) {
destroy_init_expr_recursive(cur_expr);
goto fail;
}
break;
}
#endif
default:
{
bh_assert(0);
goto fail;
}
}
@ -489,18 +634,42 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
/* There should be only one value left on the init value stack */
if (!pop_const_expr_stack(&const_expr_ctx, &flag, type, &cur_value,
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
&cur_expr,
#endif
error_buf, error_buf_size)) {
bh_assert(0);
goto fail;
}
bh_assert(const_expr_ctx.sp == 0);
if (const_expr_ctx.sp != 0) {
set_error_buf(error_buf, error_buf_size,
"type mismatch: illegal constant opcode sequence");
goto fail;
}
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
if (cur_expr != NULL) {
bh_memcpy_s(init_expr, sizeof(InitializerExpression), cur_expr,
sizeof(InitializerExpression));
wasm_runtime_free(cur_expr);
}
else {
init_expr->init_expr_type = flag;
init_expr->u.unary.v = cur_value;
}
#else
init_expr->init_expr_type = flag;
init_expr->u = cur_value;
init_expr->u.unary.v = cur_value;
#endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */
*p_buf = p;
destroy_const_expr_stack(&const_expr_ctx);
destroy_const_expr_stack(&const_expr_ctx, false);
return true;
fail:
destroy_const_expr_stack(&const_expr_ctx, true);
return false;
}
static bool
@ -1385,13 +1554,14 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
* global.get instructions are
* only allowed to refer to imported globals.
*/
uint32 target_global_index = global->init_expr.u.global_index;
uint32 target_global_index =
global->init_expr.u.unary.v.global_index;
bh_assert(target_global_index < module->import_global_count);
(void)target_global_index;
}
else if (INIT_EXPR_TYPE_FUNCREF_CONST
== global->init_expr.init_expr_type) {
bh_assert(global->init_expr.u.ref_index
bh_assert(global->init_expr.u.unary.v.ref_index
< module->import_function_count
+ module->function_count);
}
@ -1575,7 +1745,7 @@ load_func_index_vec(const uint8 **p_buf, const uint8 *buf_end,
}
init_expr->init_expr_type = INIT_EXPR_TYPE_FUNCREF_CONST;
init_expr->u.ref_index = function_index;
init_expr->u.unary.v.ref_index = function_index;
}
*p_buf = p;
@ -1890,6 +2060,9 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
if (!(dataseg = module->data_segments[i] = loader_malloc(
sizeof(WASMDataSeg), error_buf, error_buf_size))) {
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
destroy_init_expr(&init_expr);
#endif
return false;
}
@ -2778,7 +2951,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
&& global->init_expr.init_expr_type
== INIT_EXPR_TYPE_I32_CONST) {
aux_heap_base_global = global;
aux_heap_base = (uint64)(uint32)global->init_expr.u.i32;
aux_heap_base =
(uint64)(uint32)global->init_expr.u.unary.v.i32;
aux_heap_base_global_index = export->index;
LOG_VERBOSE("Found aux __heap_base global, value: %" PRIu64,
aux_heap_base);
@ -2798,7 +2972,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
&& global->init_expr.init_expr_type
== INIT_EXPR_TYPE_I32_CONST) {
aux_data_end_global = global;
aux_data_end = (uint64)(uint32)global->init_expr.u.i32;
aux_data_end =
(uint64)(uint32)global->init_expr.u.unary.v.i32;
aux_data_end_global_index = export->index;
LOG_VERBOSE("Found aux __data_end global, value: %" PRIu64,
aux_data_end);
@ -2838,10 +3013,11 @@ load_from_sections(WASMModule *module, WASMSection *sections,
&& global->type.val_type == VALUE_TYPE_I32
&& global->init_expr.init_expr_type
== INIT_EXPR_TYPE_I32_CONST
&& (uint64)(uint32)global->init_expr.u.i32
&& (uint64)(uint32)global->init_expr.u.unary.v.i32
<= aux_heap_base) {
aux_stack_top_global = global;
aux_stack_top = (uint64)(uint32)global->init_expr.u.i32;
aux_stack_top =
(uint64)(uint32)global->init_expr.u.unary.v.i32;
module->aux_stack_top_global_index =
module->import_global_count + global_index;
module->aux_stack_bottom = aux_stack_top;
@ -3448,8 +3624,14 @@ wasm_loader_unload(WASMModule *module)
if (module->memories)
wasm_runtime_free(module->memories);
if (module->globals)
if (module->globals) {
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
for (i = 0; i < module->global_count; i++) {
destroy_init_expr(&module->globals[i].init_expr);
}
#endif
wasm_runtime_free(module->globals);
}
if (module->exports)
wasm_runtime_free(module->exports);
@ -3458,6 +3640,9 @@ wasm_loader_unload(WASMModule *module)
for (i = 0; i < module->table_seg_count; i++) {
if (module->table_segments[i].init_values)
wasm_runtime_free(module->table_segments[i].init_values);
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
destroy_init_expr(&module->table_segments[i].base_offset);
#endif
}
wasm_runtime_free(module->table_segments);
}
@ -3467,6 +3652,9 @@ wasm_loader_unload(WASMModule *module)
if (module->data_segments[i]) {
if (module->data_segments[i]->is_data_cloned)
wasm_runtime_free(module->data_segments[i]->data);
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
destroy_init_expr(&module->data_segments[i]->base_offset);
#endif
wasm_runtime_free(module->data_segments[i]);
}
}
@ -7320,7 +7508,8 @@ re_scan:
== VALUE_TYPE_FUNCREF
&& module->globals[i].init_expr.init_expr_type
== INIT_EXPR_TYPE_FUNCREF_CONST
&& module->globals[i].init_expr.u.u32 == func_idx) {
&& module->globals[i].init_expr.u.unary.v.ref_index
== func_idx) {
func_declared = true;
break;
}
@ -7334,7 +7523,8 @@ re_scan:
i++, table_seg++) {
if (table_seg->elem_type == VALUE_TYPE_FUNCREF) {
for (j = 0; j < table_seg->value_count; j++) {
if (table_seg->init_values[j].u.ref_index
if (table_seg->init_values[j]
.u.unary.v.ref_index
== func_idx) {
func_declared = true;
break;

View File

@ -1165,6 +1165,81 @@ instantiate_array_global_recursive(WASMModule *module,
}
#endif
static bool
get_init_value_recursive(WASMModule *module, InitializerExpression *expr,
WASMGlobalInstance *globals, WASMValue *value,
char *error_buf, uint32 error_buf_size)
{
uint8 flag = expr->init_expr_type;
switch (flag) {
case INIT_EXPR_TYPE_GET_GLOBAL:
{
if (!check_global_init_expr(module, expr->u.unary.v.global_index,
error_buf, error_buf_size)) {
goto fail;
}
*value = globals[expr->u.unary.v.global_index].initial_value;
break;
}
case INIT_EXPR_TYPE_I32_CONST:
case INIT_EXPR_TYPE_I64_CONST:
{
*value = expr->u.unary.v;
break;
}
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
{
WASMValue l_value, r_value;
if (!expr->u.binary.l_expr || !expr->u.binary.r_expr) {
goto fail;
}
if (!get_init_value_recursive(module, expr->u.binary.l_expr,
globals, &l_value, error_buf,
error_buf_size)) {
goto fail;
}
if (!get_init_value_recursive(module, expr->u.binary.r_expr,
globals, &r_value, error_buf,
error_buf_size)) {
goto fail;
}
if (flag == INIT_EXPR_TYPE_I32_ADD) {
value->i32 = l_value.i32 + r_value.i32;
}
else if (flag == INIT_EXPR_TYPE_I32_SUB) {
value->i32 = l_value.i32 - r_value.i32;
}
else if (flag == INIT_EXPR_TYPE_I32_MUL) {
value->i32 = l_value.i32 * r_value.i32;
}
else if (flag == INIT_EXPR_TYPE_I64_ADD) {
value->i64 = l_value.i64 + r_value.i64;
}
else if (flag == INIT_EXPR_TYPE_I64_SUB) {
value->i64 = l_value.i64 - r_value.i64;
}
else if (flag == INIT_EXPR_TYPE_I64_MUL) {
value->i64 = l_value.i64 * r_value.i64;
}
break;
}
#endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */
default:
goto fail;
}
return true;
fail:
return false;
}
/**
* Instantiate globals in a module.
*/
@ -1209,7 +1284,7 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
/* The linked global instance has been initialized, we
just need to copy the value. */
global->initial_value =
global_import->import_global_linked->init_expr.u;
global_import->import_global_linked->init_expr.u.unary.v;
}
else
#endif
@ -1245,17 +1320,23 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
#endif
switch (flag) {
case INIT_EXPR_TYPE_I32_CONST:
case INIT_EXPR_TYPE_I64_CONST:
case INIT_EXPR_TYPE_GET_GLOBAL:
#if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
case INIT_EXPR_TYPE_I32_ADD:
case INIT_EXPR_TYPE_I32_SUB:
case INIT_EXPR_TYPE_I32_MUL:
case INIT_EXPR_TYPE_I64_ADD:
case INIT_EXPR_TYPE_I64_SUB:
case INIT_EXPR_TYPE_I64_MUL:
#endif
{
if (!check_global_init_expr(module, init_expr->u.global_index,
error_buf, error_buf_size)) {
if (!get_init_value_recursive(module, init_expr, globals,
&global->initial_value, error_buf,
error_buf_size)) {
goto fail;
}
bh_memcpy_s(
&(global->initial_value), sizeof(WASMValue),
&(globals[init_expr->u.global_index].initial_value),
sizeof(globals[init_expr->u.global_index].initial_value));
break;
}
#if WASM_ENABLE_GC != 0
@ -1267,11 +1348,12 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
uint32 type_idx;
if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
init_values = (WASMStructNewInitValues *)init_expr->u.data;
init_values =
(WASMStructNewInitValues *)init_expr->u.unary.v.data;
type_idx = init_values->type_idx;
}
else {
type_idx = init_expr->u.type_index;
type_idx = init_expr->u.unary.v.type_index;
}
struct_obj = instantiate_struct_global_recursive(
@ -1294,12 +1376,14 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
uint32 type_idx, len;
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
type_idx = init_expr->u.array_new_default.type_index;
len = init_expr->u.array_new_default.length;
type_idx =
init_expr->u.unary.v.array_new_default.type_index;
len = init_expr->u.unary.v.array_new_default.length;
array_init_value = &empty_value;
}
else {
init_values = (WASMArrayNewInitValues *)init_expr->u.data;
init_values =
(WASMArrayNewInitValues *)init_expr->u.unary.v.data;
type_idx = init_values->type_idx;
len = init_values->length;
@ -1318,13 +1402,12 @@ globals_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
case INIT_EXPR_TYPE_I31_NEW:
{
global->initial_value.gc_obj =
(wasm_obj_t)wasm_i31_obj_new(init_expr->u.i32);
(wasm_obj_t)wasm_i31_obj_new(init_expr->u.unary.v.i32);
break;
}
#endif /* end of WASM_ENABLE_GC != 0 */
default:
bh_memcpy_s(&(global->initial_value), sizeof(WASMValue),
&(init_expr->u), sizeof(init_expr->u));
global->initial_value = init_expr->u.unary.v;
break;
}
@ -2698,6 +2781,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
uint8 *memory_data = NULL;
uint64 memory_size = 0;
WASMDataSeg *data_seg = module->data_segments[i];
WASMValue offset_value;
#if WASM_ENABLE_BULK_MEMORY != 0
if (data_seg->is_passive)
@ -2717,54 +2801,37 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
(uint64)memory->num_bytes_per_page * memory->cur_page_count;
bh_assert(memory_data || memory_size == 0);
bh_assert(data_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL
|| data_seg->base_offset.init_expr_type
== (memory->is_memory64 ? INIT_EXPR_TYPE_I64_CONST
: INIT_EXPR_TYPE_I32_CONST));
uint8 offset_flag = data_seg->base_offset.init_expr_type;
bh_assert(offset_flag == INIT_EXPR_TYPE_GET_GLOBAL
|| (memory->is_memory64 ? is_valid_i64_offset(offset_flag)
: is_valid_i32_offset(offset_flag)));
if (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
if (!check_global_init_expr(module,
data_seg->base_offset.u.global_index,
error_buf, error_buf_size)) {
goto fail;
}
if (!get_init_value_recursive(module, &data_seg->base_offset, globals,
&offset_value, error_buf,
error_buf_size)) {
goto fail;
}
if (offset_flag == INIT_EXPR_TYPE_GET_GLOBAL) {
if (!globals
|| globals[data_seg->base_offset.u.global_index].type
|| globals[data_seg->base_offset.u.unary.v.global_index].type
!= (memory->is_memory64 ? VALUE_TYPE_I64
: VALUE_TYPE_I32)) {
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
goto fail;
}
#if WASM_ENABLE_MEMORY64 != 0
if (memory->is_memory64) {
base_offset =
(uint64)globals[data_seg->base_offset.u.global_index]
.initial_value.i64;
}
else
#endif
{
base_offset =
(uint32)globals[data_seg->base_offset.u.global_index]
.initial_value.i32;
}
}
else {
#if WASM_ENABLE_MEMORY64 != 0
if (memory->is_memory64) {
base_offset = (uint64)data_seg->base_offset.u.i64;
}
else
#endif
{
base_offset = (uint32)data_seg->base_offset.u.i32;
}
}
#if WASM_ENABLE_MEMORY64 != 0
if (memory->is_memory64) {
base_offset = (uint64)offset_value.i64;
}
else
#endif
{
base_offset = (uint32)offset_value.i32;
}
/* check offset */
if (base_offset > memory_size) {
#if WASM_ENABLE_MEMORY64 != 0
@ -2842,36 +2909,39 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|| table->init_expr.init_expr_type == INIT_EXPR_TYPE_REFNULL_CONST);
if (table->init_expr.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
if (!check_global_init_expr(module, table->init_expr.u.global_index,
if (!check_global_init_expr(module,
table->init_expr.u.unary.v.global_index,
error_buf, error_buf_size)) {
goto fail;
}
table->init_expr.u.gc_obj =
globals[table->init_expr.u.global_index].initial_value.gc_obj;
table->init_expr.u.unary.v.gc_obj =
globals[table->init_expr.u.unary.v.global_index]
.initial_value.gc_obj;
}
else if (table->init_expr.init_expr_type
== INIT_EXPR_TYPE_FUNCREF_CONST) {
uint32 func_idx = table->init_expr.u.ref_index;
uint32 func_idx = table->init_expr.u.unary.v.ref_index;
if (func_idx != UINT32_MAX) {
if (!(table->init_expr.u.gc_obj =
if (!(table->init_expr.u.unary.v.gc_obj =
wasm_create_func_obj(module_inst, func_idx, false,
error_buf, error_buf_size)))
goto fail;
}
else {
table->init_expr.u.gc_obj = NULL_REF;
table->init_expr.u.unary.v.gc_obj = NULL_REF;
}
}
else if (table->init_expr.init_expr_type
== INIT_EXPR_TYPE_REFNULL_CONST) {
table->init_expr.u.gc_obj = NULL_REF;
table->init_expr.u.unary.v.gc_obj = NULL_REF;
}
LOG_DEBUG("Init table [%d] elements from [%d] to [%d] as: %p", i, 0,
table_inst->cur_size, (void *)table->init_expr.u.gc_obj);
table_inst->cur_size,
(void *)table->init_expr.u.unary.v.gc_obj);
for (j = 0; j < table_inst->cur_size; j++) {
*(table_data + j) = table->init_expr.u.gc_obj;
*(table_data + j) = table->init_expr.u.unary.v.gc_obj;
}
}
#endif /* end of WASM_ENABLE_GC != 0 */
@ -2883,6 +2953,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
/* has check it in loader */
WASMTableInstance *table = module_inst->tables[table_seg->table_index];
table_elem_type_t *table_data;
WASMValue offset_value;
uint32 j;
#if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
uint8 tbl_elem_type;
@ -2941,48 +3012,37 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
continue;
#endif
uint8 offset_flag = table_seg->base_offset.init_expr_type;
#if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
bh_assert(table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_I32_CONST
|| table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL
|| table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_FUNCREF_CONST
|| table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_REFNULL_CONST);
bh_assert(offset_flag == INIT_EXPR_TYPE_GET_GLOBAL
|| offset_flag == INIT_EXPR_TYPE_FUNCREF_CONST
|| offset_flag == INIT_EXPR_TYPE_REFNULL_CONST
|| is_valid_i32_offset(offset_flag));
#else
bh_assert(table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_I32_CONST
|| table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL);
bh_assert(offset_flag == INIT_EXPR_TYPE_GET_GLOBAL
|| is_valid_i32_offset(offset_flag));
#endif
/* init vec(funcidx) or vec(expr) */
if (table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL) {
if (!check_global_init_expr(module,
table_seg->base_offset.u.global_index,
error_buf, error_buf_size)) {
goto fail;
}
if (!get_init_value_recursive(module, &table_seg->base_offset, globals,
&offset_value, error_buf,
error_buf_size)) {
goto fail;
}
if (offset_flag == INIT_EXPR_TYPE_GET_GLOBAL) {
if (!globals
|| globals[table_seg->base_offset.u.global_index].type
|| globals[table_seg->base_offset.u.unary.v.global_index].type
!= VALUE_TYPE_I32) {
set_error_buf(error_buf, error_buf_size,
"type mismatch: elements segment does not fit");
goto fail;
}
table_seg->base_offset.u.i32 =
globals[table_seg->base_offset.u.global_index]
.initial_value.i32;
}
/* check offset since length might negative */
if ((uint32)table_seg->base_offset.u.i32 > table->cur_size) {
LOG_DEBUG("base_offset(%d) > table->cur_size(%d)",
table_seg->base_offset.u.i32, table->cur_size);
if ((uint32)offset_value.i32 > table->cur_size) {
LOG_DEBUG("base_offset(%d) > table->cur_size(%d)", offset_value.i32,
table->cur_size);
#if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
set_error_buf(error_buf, error_buf_size,
"out of bounds table access");
@ -2995,9 +3055,9 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
/* check offset + length(could be zero) */
length = table_seg->value_count;
if ((uint32)table_seg->base_offset.u.i32 + length > table->cur_size) {
if ((uint32)offset_value.i32 + length > table->cur_size) {
LOG_DEBUG("base_offset(%d) + length(%d)> table->cur_size(%d)",
table_seg->base_offset.u.i32, length, table->cur_size);
offset_value.i32, length, table->cur_size);
#if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
set_error_buf(error_buf, error_buf_size,
"out of bounds table access");
@ -3027,10 +3087,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
case INIT_EXPR_TYPE_FUNCREF_CONST:
{
#if WASM_ENABLE_GC == 0
ref = (void *)(uintptr_t)init_expr->u.ref_index;
ref = (void *)(uintptr_t)init_expr->u.unary.v.ref_index;
#else
WASMFuncObjectRef func_obj;
uint32 func_idx = init_expr->u.ref_index;
uint32 func_idx = init_expr->u.unary.v.ref_index;
/* UINT32_MAX indicates that it is a null reference */
if (func_idx != UINT32_MAX) {
if (!(func_obj = wasm_create_func_obj(
@ -3049,14 +3109,14 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
#if WASM_ENABLE_GC != 0
case INIT_EXPR_TYPE_GET_GLOBAL:
{
if (!check_global_init_expr(module,
init_expr->u.global_index,
error_buf, error_buf_size)) {
if (!check_global_init_expr(
module, init_expr->u.unary.v.global_index,
error_buf, error_buf_size)) {
goto fail;
}
ref =
globals[init_expr->u.global_index].initial_value.gc_obj;
ref = globals[init_expr->u.unary.v.global_index]
.initial_value.gc_obj;
break;
}
case INIT_EXPR_TYPE_STRUCT_NEW:
@ -3069,12 +3129,12 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
uint32 type_idx;
if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
init_values =
(WASMStructNewInitValues *)init_expr->u.data;
init_values = (WASMStructNewInitValues *)
init_expr->u.unary.v.data;
type_idx = init_values->type_idx;
}
else {
type_idx = init_expr->u.type_index;
type_idx = init_expr->u.unary.v.type_index;
}
struct_type = (WASMStructType *)module->types[type_idx];
@ -3125,13 +3185,14 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
uint32 type_idx, len;
if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
type_idx = init_expr->u.array_new_default.type_index;
len = init_expr->u.array_new_default.length;
type_idx =
init_expr->u.unary.v.array_new_default.type_index;
len = init_expr->u.unary.v.array_new_default.length;
arr_init_val = &empty_val;
}
else {
init_values =
(WASMArrayNewInitValues *)init_expr->u.data;
(WASMArrayNewInitValues *)init_expr->u.unary.v.data;
type_idx = init_values->type_idx;
len = init_values->length;
@ -3177,14 +3238,14 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
}
case INIT_EXPR_TYPE_I31_NEW:
{
ref = (wasm_obj_t)wasm_i31_obj_new(init_expr->u.i32);
ref =
(wasm_obj_t)wasm_i31_obj_new(init_expr->u.unary.v.i32);
break;
}
#endif /* end of WASM_ENABLE_GC != 0 */
}
*(table_data + table_seg->base_offset.u.i32 + j) =
(table_elem_type_t)ref;
*(table_data + offset_value.i32 + j) = (table_elem_type_t)ref;
}
}
@ -4706,10 +4767,10 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
for (i = 0; i < length; i++) {
#if WASM_ENABLE_GC != 0
/* UINT32_MAX indicates that it is a null ref */
if (init_values[i].u.ref_index != UINT32_MAX) {
if (!(func_obj = wasm_create_func_obj(module_inst,
init_values[i].u.ref_index,
true, NULL, 0))) {
if (init_values[i].u.unary.v.ref_index != UINT32_MAX) {
if (!(func_obj = wasm_create_func_obj(
module_inst, init_values[i].u.unary.v.ref_index, true,
NULL, 0))) {
wasm_set_exception(module_inst, "null function reference");
return;
}
@ -4719,7 +4780,7 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
table_elems[i] = NULL_REF;
}
#else
table_elems[i] = init_values[i].u.ref_index;
table_elems[i] = init_values[i].u.unary.v.ref_index;
#endif
}
}

View File

@ -191,7 +191,7 @@ bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
error = __wasi_sock_bind(sockfd, &wasi_addr);
HANDLE_ERROR(error)
return __WASI_ERRNO_SUCCESS;
return 0;
}
int
@ -212,7 +212,7 @@ connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
error = __wasi_sock_connect(sockfd, &wasi_addr);
HANDLE_ERROR(error)
return __WASI_ERRNO_SUCCESS;
return 0;
}
int
@ -220,7 +220,7 @@ listen(int sockfd, int backlog)
{
__wasi_errno_t error = __wasi_sock_listen(sockfd, backlog);
HANDLE_ERROR(error)
return __WASI_ERRNO_SUCCESS;
return 0;
}
ssize_t
@ -375,7 +375,7 @@ socket(int domain, int type, int protocol)
af = INET6;
}
else {
return __WASI_ERRNO_NOPROTOOPT;
HANDLE_ERROR(__WASI_ERRNO_NOPROTOOPT)
}
if (SOCK_DGRAM == type) {
@ -385,7 +385,7 @@ socket(int domain, int type, int protocol)
socktype = SOCKET_STREAM;
}
else {
return __WASI_ERRNO_NOPROTOOPT;
HANDLE_ERROR(__WASI_ERRNO_NOPROTOOPT)
}
error = __wasi_sock_open(poolfd, af, socktype, &sockfd);
@ -408,7 +408,7 @@ getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
error = wasi_addr_to_sockaddr(&wasi_addr, addr, addrlen);
HANDLE_ERROR(error)
return __WASI_ERRNO_SUCCESS;
return 0;
}
int
@ -425,7 +425,7 @@ getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
error = wasi_addr_to_sockaddr(&wasi_addr, addr, addrlen);
HANDLE_ERROR(error)
return __WASI_ERRNO_SUCCESS;
return 0;
}
struct aibuf {
@ -541,10 +541,10 @@ getaddrinfo(const char *node, const char *service, const struct addrinfo *hints,
}
} while (max_info_size > addr_info_size);
addr_info_size = max_info_size;
if (addr_info_size == 0) {
free(addr_info);
*res = NULL;
return __WASI_ERRNO_SUCCESS;
HANDLE_ERROR(__WASI_ERRNO_NOENT)
}
aibuf_res =
@ -556,10 +556,6 @@ getaddrinfo(const char *node, const char *service, const struct addrinfo *hints,
*res = &aibuf_res[0].ai;
if (addr_info_size) {
addr_info_size = max_info_size;
}
for (i = 0; i < addr_info_size; i++) {
struct addrinfo *ai = &aibuf_res[i].ai;
ai->ai_addr = (struct sockaddr *)&aibuf_res[i].sa;
@ -610,6 +606,7 @@ get_sol_socket_option(int sockfd, int optname, void *__restrict optval,
uint64_t timeout_us;
bool is_linger_enabled;
int linger_s;
__wasi_fdstat_t sb;
switch (optname) {
case SO_RCVTIMEO:
@ -617,38 +614,38 @@ get_sol_socket_option(int sockfd, int optname, void *__restrict optval,
error = __wasi_sock_get_recv_timeout(sockfd, &timeout_us);
HANDLE_ERROR(error);
*(struct timeval *)optval = time_us_to_timeval(timeout_us);
return error;
return 0;
case SO_SNDTIMEO:
assert(*optlen == sizeof(struct timeval));
error = __wasi_sock_get_send_timeout(sockfd, &timeout_us);
HANDLE_ERROR(error);
*(struct timeval *)optval = time_us_to_timeval(timeout_us);
return error;
return 0;
case SO_SNDBUF:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_send_buf_size(sockfd, (size_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case SO_RCVBUF:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_recv_buf_size(sockfd, (size_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case SO_KEEPALIVE:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_keep_alive(sockfd, (bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case SO_REUSEADDR:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_reuse_addr(sockfd, (bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case SO_REUSEPORT:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_reuse_port(sockfd, (bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case SO_LINGER:
assert(*optlen == sizeof(struct linger));
error =
@ -656,16 +653,32 @@ get_sol_socket_option(int sockfd, int optname, void *__restrict optval,
HANDLE_ERROR(error);
((struct linger *)optval)->l_onoff = (int)is_linger_enabled;
((struct linger *)optval)->l_linger = linger_s;
return error;
return 0;
case SO_BROADCAST:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_broadcast(sockfd, (bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case SO_TYPE:
assert(*optlen == sizeof(int));
error = __wasi_fd_fdstat_get(sockfd, &sb);
HANDLE_ERROR(error);
switch (sb.fs_filetype) {
case __WASI_FILETYPE_SOCKET_DGRAM:
*(int *)optval = SOCK_DGRAM;
break;
case __WASI_FILETYPE_SOCKET_STREAM:
*(int *)optval = SOCK_STREAM;
break;
default:
errno = __WASI_ERRNO_NOTSOCK;
return -1;
}
return 0;
default:
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}
@ -679,32 +692,32 @@ get_ipproto_tcp_option(int sockfd, int optname, void *__restrict optval,
assert(*optlen == sizeof(uint32_t));
error = __wasi_sock_get_tcp_keep_idle(sockfd, (uint32_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case TCP_KEEPINTVL:
assert(*optlen == sizeof(uint32_t));
error = __wasi_sock_get_tcp_keep_intvl(sockfd, (uint32_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case TCP_FASTOPEN_CONNECT:
assert(*optlen == sizeof(int));
error =
__wasi_sock_get_tcp_fastopen_connect(sockfd, (bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case TCP_NODELAY:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_tcp_no_delay(sockfd, (bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case TCP_QUICKACK:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_tcp_quick_ack(sockfd, (bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
default:
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}
@ -720,21 +733,21 @@ get_ipproto_ip_option(int sockfd, int optname, void *__restrict optval,
error = __wasi_sock_get_ip_multicast_loop(sockfd, false,
(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case IP_TTL:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_ip_ttl(sockfd, (uint8_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case IP_MULTICAST_TTL:
assert(*optlen == sizeof(int));
error = __wasi_sock_get_ip_multicast_ttl(sockfd, (uint8_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
default:
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}
@ -749,17 +762,17 @@ get_ipproto_ipv6_option(int sockfd, int optname, void *__restrict optval,
assert(*optlen == sizeof(int));
error = __wasi_sock_get_ipv6_only(sockfd, (bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case IPV6_MULTICAST_LOOP:
assert(*optlen == sizeof(int));
error =
__wasi_sock_get_ip_multicast_loop(sockfd, true, (bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
default:
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}
@ -781,7 +794,7 @@ getsockopt(int sockfd, int level, int optname, void *__restrict optval,
default:
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}
@ -799,7 +812,7 @@ set_sol_socket_option(int sockfd, int optname, const void *optval,
timeout_us = timeval_to_time_us(*(struct timeval *)optval);
error = __wasi_sock_set_recv_timeout(sockfd, timeout_us);
HANDLE_ERROR(error);
return error;
return 0;
}
case SO_SNDTIMEO:
{
@ -807,42 +820,42 @@ set_sol_socket_option(int sockfd, int optname, const void *optval,
timeout_us = timeval_to_time_us(*(struct timeval *)optval);
error = __wasi_sock_set_send_timeout(sockfd, timeout_us);
HANDLE_ERROR(error);
return error;
return 0;
}
case SO_SNDBUF:
{
assert(optlen == sizeof(int));
error = __wasi_sock_set_send_buf_size(sockfd, *(size_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
}
case SO_RCVBUF:
{
assert(optlen == sizeof(int));
error = __wasi_sock_set_recv_buf_size(sockfd, *(size_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
}
case SO_KEEPALIVE:
{
assert(optlen == sizeof(int));
error = __wasi_sock_set_keep_alive(sockfd, *(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
}
case SO_REUSEADDR:
{
assert(optlen == sizeof(int));
error = __wasi_sock_set_reuse_addr(sockfd, *(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
}
case SO_REUSEPORT:
{
assert(optlen == sizeof(int));
error = __wasi_sock_set_reuse_port(sockfd, *(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
}
case SO_LINGER:
{
@ -851,20 +864,20 @@ set_sol_socket_option(int sockfd, int optname, const void *optval,
error = __wasi_sock_set_linger(sockfd, (bool)linger_opt->l_onoff,
linger_opt->l_linger);
HANDLE_ERROR(error);
return error;
return 0;
}
case SO_BROADCAST:
{
assert(optlen == sizeof(int));
error = __wasi_sock_set_broadcast(sockfd, *(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
}
default:
{
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}
}
@ -880,32 +893,32 @@ set_ipproto_tcp_option(int sockfd, int optname, const void *optval,
assert(optlen == sizeof(int));
error = __wasi_sock_set_tcp_no_delay(sockfd, *(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case TCP_KEEPIDLE:
assert(optlen == sizeof(uint32_t));
error = __wasi_sock_set_tcp_keep_idle(sockfd, *(uint32_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case TCP_KEEPINTVL:
assert(optlen == sizeof(uint32_t));
error = __wasi_sock_set_tcp_keep_intvl(sockfd, *(uint32_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case TCP_FASTOPEN_CONNECT:
assert(optlen == sizeof(int));
error =
__wasi_sock_set_tcp_fastopen_connect(sockfd, *(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case TCP_QUICKACK:
assert(optlen == sizeof(int));
error = __wasi_sock_set_tcp_quick_ack(sockfd, *(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
default:
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}
@ -923,7 +936,7 @@ set_ipproto_ip_option(int sockfd, int optname, const void *optval,
error = __wasi_sock_set_ip_multicast_loop(sockfd, false,
*(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case IP_ADD_MEMBERSHIP:
assert(optlen == sizeof(struct ip_mreq));
ip_mreq_opt = (struct ip_mreq *)optval;
@ -933,7 +946,7 @@ set_ipproto_ip_option(int sockfd, int optname, const void *optval,
error = __wasi_sock_set_ip_add_membership(
sockfd, &imr_multiaddr, ip_mreq_opt->imr_interface.s_addr);
HANDLE_ERROR(error);
return error;
return 0;
case IP_DROP_MEMBERSHIP:
assert(optlen == sizeof(struct ip_mreq));
ip_mreq_opt = (struct ip_mreq *)optval;
@ -943,22 +956,22 @@ set_ipproto_ip_option(int sockfd, int optname, const void *optval,
error = __wasi_sock_set_ip_drop_membership(
sockfd, &imr_multiaddr, ip_mreq_opt->imr_interface.s_addr);
HANDLE_ERROR(error);
return error;
return 0;
case IP_TTL:
assert(optlen == sizeof(int));
error = __wasi_sock_set_ip_ttl(sockfd, *(uint8_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case IP_MULTICAST_TTL:
assert(optlen == sizeof(int));
error =
__wasi_sock_set_ip_multicast_ttl(sockfd, *(uint8_t *)optval);
HANDLE_ERROR(error);
return error;
return 0;
default:
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}
@ -975,13 +988,13 @@ set_ipproto_ipv6_option(int sockfd, int optname, const void *optval,
assert(optlen == sizeof(int));
error = __wasi_sock_set_ipv6_only(sockfd, *(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case IPV6_MULTICAST_LOOP:
assert(optlen == sizeof(int));
error = __wasi_sock_set_ip_multicast_loop(sockfd, true,
*(bool *)optval);
HANDLE_ERROR(error);
return error;
return 0;
case IPV6_JOIN_GROUP:
assert(optlen == sizeof(struct ipv6_mreq));
ipv6_mreq_opt = (struct ipv6_mreq *)optval;
@ -992,7 +1005,7 @@ set_ipproto_ipv6_option(int sockfd, int optname, const void *optval,
error = __wasi_sock_set_ip_add_membership(
sockfd, &imr_multiaddr, ipv6_mreq_opt->ipv6mr_interface);
HANDLE_ERROR(error);
return error;
return 0;
case IPV6_LEAVE_GROUP:
assert(optlen == sizeof(struct ipv6_mreq));
ipv6_mreq_opt = (struct ipv6_mreq *)optval;
@ -1003,11 +1016,11 @@ set_ipproto_ipv6_option(int sockfd, int optname, const void *optval,
error = __wasi_sock_set_ip_drop_membership(
sockfd, &imr_multiaddr, ipv6_mreq_opt->ipv6mr_interface);
HANDLE_ERROR(error);
return error;
return 0;
default:
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}
@ -1029,6 +1042,6 @@ setsockopt(int sockfd, int level, int optname, const void *optval,
default:
error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error);
return error;
return 0;
}
}

View File

@ -375,6 +375,9 @@ wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
if (total_size == 0) {
total_size = 1; /* avoid user-triggered 0-sized allocation */
}
if (total_size >= UINT32_MAX
|| !(iovec_begin = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1;
@ -430,6 +433,9 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
if (total_size == 0) {
total_size = 1; /* avoid user-triggered 0-sized allocation */
}
if (total_size >= UINT32_MAX
|| !(ciovec_begin = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1;
@ -484,6 +490,9 @@ wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
return (wasi_errno_t)-1;
total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
if (total_size == 0) {
total_size = 1; /* avoid user-triggered 0-sized allocation */
}
if (total_size >= UINT32_MAX
|| !(iovec_begin = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1;
@ -654,6 +663,9 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
return (wasi_errno_t)-1;
total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
if (total_size == 0) {
total_size = 1; /* avoid user-triggered 0-sized allocation */
}
if (total_size >= UINT32_MAX
|| !(ciovec_begin = wasm_runtime_malloc((uint32)total_size)))
return (wasi_errno_t)-1;

View File

@ -17,6 +17,10 @@ extern char const *LLAMA_COMMIT;
extern char const *LLAMA_COMPILER;
extern char const *LLAMA_BUILD_TARGET;
#if WASM_ENABLE_WASI_EPHEMERAL_NN == 0
#error This backend doesn't support legacy "wasi_nn" abi. Please enable WASM_ENABLE_WASI_EPHEMERAL_NN.
#endif
// compatible with WasmEdge
// https://github.com/second-state/WasmEdge-WASINN-examples/blob/master/wasmedge-ggml/README.md#parameters
// https://github.com/WasmEdge/WasmEdge/blob/master/plugins/wasi_nn/ggml.cpp
@ -407,6 +411,11 @@ set_input(void *ctx, graph_execution_context exec_ctx, uint32_t index,
return runtime_error;
}
if (index != 0) {
NN_ERR_PRINTF("Invalid input index %d", index);
return invalid_argument;
}
// tensor->data is the prompt string.
char *prompt_text = (char *)wasi_nn_tensor->data.buf;
uint32_t prompt_text_len = wasi_nn_tensor->data.size;

View File

@ -9,6 +9,10 @@
#include "openvino/c/openvino.h"
#if WASM_ENABLE_WASI_EPHEMERAL_NN == 0
#error This backend doesn't support legacy "wasi_nn" abi. Please enable WASM_ENABLE_WASI_EPHEMERAL_NN.
#endif
/*
* refer to
* https://docs.openvino.ai/2024/openvino-workflow/running-inference/integrate-openvino-with-your-application.html

View File

@ -373,8 +373,8 @@ is_addrinfo_supported(struct addrinfo *info)
(info->ai_family == AF_INET || info->ai_family == AF_INET6)
// Allow only UDP and TCP
&& (info->ai_socktype == SOCK_DGRAM || info->ai_socktype == SOCK_STREAM)
&& (info->ai_protocol == IPPROTO_TCP
|| info->ai_protocol == IPPROTO_UDP);
&& (info->ai_protocol == IPPROTO_TCP || info->ai_protocol == IPPROTO_UDP
|| info->ai_protocol == 0);
}
int
@ -406,12 +406,11 @@ os_socket_addr_resolve(const char *host, const char *service,
res = result;
while (res) {
if (!is_addrinfo_supported(res)) {
res = res->ai_next;
continue;
}
if (addr_info_size > pos) {
if (!is_addrinfo_supported(res)) {
res = res->ai_next;
continue;
}
ret =
sockaddr_to_bh_sockaddr(res->ai_addr, &addr_info[pos].sockaddr);

View File

@ -59,7 +59,7 @@ b_memcpy_wa(void *s1, unsigned int s1max, const void *s2, unsigned int n)
*dest++ = *p_byte_read++;
}
}
/* read meaning word(s) */
/* read remaining word(s) */
else {
if ((char *)p + 4 >= src + n) {
for (ps = (char *)p; ps < src + n; ps++) {

View File

@ -170,7 +170,7 @@ bh_free_msg(bh_queue_node *msg)
return;
}
// note: sometime we just use the payload pointer for a integer value
// note: sometimes we just use the payload pointer for an integer value
// len!=0 is the only indicator about the body is an allocated buffer.
if (msg->body && msg->len)
bh_queue_free(msg->body);

View File

@ -44,22 +44,22 @@ bh_get_tick_ms()
uint32
bh_get_elpased_ms(uint32 *last_system_clock)
{
uint32 elpased_ms;
/* attention: the bh_get_tick_ms() return 64 bits integer, but
the bh_get_elpased_ms() is designed to use 32 bits clock count */
uint32 elapsed_ms;
/* attention: the bh_get_tick_ms() returns a 64-bit integer, but
bh_get_elpased_ms() is designed to use a 32-bit clock count */
uint32 now = (uint32)bh_get_tick_ms();
/* system clock overrun */
if (now < *last_system_clock) {
PRINT("system clock overrun!\n");
elpased_ms = now + (UINT32_MAX - *last_system_clock) + 1;
elapsed_ms = now + (UINT32_MAX - *last_system_clock) + 1;
}
else {
elpased_ms = now - *last_system_clock;
elapsed_ms = now - *last_system_clock;
}
*last_system_clock = now;
return elpased_ms;
return elapsed_ms;
}
static app_timer_t *
@ -162,7 +162,7 @@ reschedule_timer(timer_ctx_t ctx, app_timer_t *timer)
prev->id);
}
else {
/* insert at the begin */
/* insert at the beginning */
bh_assert(ctx->app_timers == NULL);
ctx->app_timers = timer;
PRINT("rescheduled timer [%d] as first\n", timer->id);
@ -213,7 +213,7 @@ release_timer_list(app_timer_t **p_list)
timer_ctx_t
create_timer_ctx(timer_callback_f timer_handler,
check_timer_expiry_f expiery_checker, int prealloc_num,
check_timer_expiry_f expiry_checker, int prealloc_num,
unsigned int owner)
{
timer_ctx_t ctx = (timer_ctx_t)BH_MALLOC(sizeof(struct _timer_ctx));
@ -225,7 +225,7 @@ create_timer_ctx(timer_callback_f timer_handler,
ctx->timer_callback = timer_handler;
ctx->pre_allocated = prealloc_num;
ctx->refresh_checker = expiery_checker;
ctx->refresh_checker = expiry_checker;
ctx->owner = owner;
while (prealloc_num > 0) {

View File

@ -17,8 +17,8 @@
/* clang-format off */
#define WAMR_VERSION_MAJOR 2
#define WAMR_VERSION_MINOR 3
#define WAMR_VERSION_PATCH 1
#define WAMR_VERSION_MINOR 4
#define WAMR_VERSION_PATCH 0
/* clang-format on */
#endif

View File

@ -293,6 +293,10 @@ Currently we only profile the memory consumption of module, module_instance and
- **WAMR_BUILD_AOT_INTRINSICS**=1/0, enable the AOT intrinsic functions, default to enable if not set. These functions can be called from the AOT code when `--disable-llvm-intrinsics` flag or `--enable-builtin-intrinsics=<intr1,intr2,...>` flag is used by wamrc to generate the AOT file.
> Note: See [Tuning the XIP intrinsic functions](./xip.md#tuning-the-xip-intrinsic-functions) for more details.
### **Enable extended constant expression**
- **WAMR_BUILD_EXTENDED_CONST_EXPR**=1/0, default to disable if not set.
> Note: See [Extended Constant Expressions](https://github.com/WebAssembly/extended-const/blob/main/proposals/extended-const/Overview.md) for more details.
### **Configurable memory access boundary check**
- **WAMR_CONFIGURABLE_BOUNDS_CHECKS**=1/0, default to disable if not set
> Note: If it is enabled, allow to run `iwasm --disable-bounds-checks` to disable the memory access boundary checks for interpreter mode.

View File

@ -0,0 +1,46 @@
# Security Issue Runbook
This runbook provides step-by-step guidance on handling a security advisory. Typically, it begins with a draft security advisory when we initiate the process outlined in this runbook. The draft security advisory is created by a contributor or a maintainer.
For information on what types of issues are considered security vulnerabilities and require a security advisory for resolution, please refer to [identifying a security issue](./security_need_to_know.md#identifying-a-security-issue).
## Step 1: Initial Response to Security Advisory
- Receive Security Advisory: When a new security advisory is received, the Incident Manager, typically the maintainer who opened the advisory, becomes the first responder. If the advisory was opened by someone else, a maintainer should take on the role of Incident Manager. The Incident Manager can hand off this role to another maintainer if necessary.
- Acknowledge Receipt: The Incident Manager should promptly acknowledge receipt of the advisory and communicate that the investigation will begin immediately. Security issues are the highest priority.
## Step 2: Investigating the Vulnerability
- Identify the Vulnerability: Reproduce the issue to understand the vulnerability. Determine which versions and platforms are affected. Fill out the advisory details with this information.
- Accept the Report: Accept the security report and create a temporary private fork to collaborate on a fix. Invite necessary helpers and stakeholders to this fork, as their input can be valuable.
## Step 3: Communication and Collaboration
- Use Non-Public Channels: Communicate through non-public channels, preferably email, during the resolution process. Avoid filing issues or pull requests on third-party repositories if they are involved.
- Workaround for Third-Party Dependencies: If third-party dependencies are involved, consider a workaround to patch the issue quickly unless the third party can release a fix promptly.
## Step 4: Finalizing and Preparing for Release
- Finalize Details: Once a fix is developed and the vulnerability is fully understood, finalize the advisory details and prepare for public release. Ensure the security issues are resolved in the private fork.
- Request CVE: Use the Big Green Button on the advisory to request a CVE number from GitHub staff.
- Advanced Disclosure Email: Decide on a disclosure date, typically within a week, and send an email to sec-announce@bytecodealliance.org about the upcoming security release. Other ways are also available to communicate the disclosure date.
## Step 5: Preparing and Testing Patch Releases
- Prepare PRs for Patch Releases: Create pull requests in the private fork for each version being patched. Ensure each PR is ready to apply cleanly and includes release notes for each release branch.
- Run Full Test Suite: Run the full test suite locally for the main branch. Attempt to run as much of the CI matrix locally as possible.
## Step 6: Public Release and Communication
- Open Version Bump PRs: Open version bump pull requests on the public repository without including patch notes or release notes for the fix.
- Manually Make PRs from Private Fork: Transfer the necessary pull requests from the private fork to the public repository.
- Merge and Trigger Releases: Merge the version bump PRs and trigger the release process.
- Publish GitHub Advisories: Delete the private forks and use the Big Green Button to publish the advisory.
- Send Security Release Email: Send a follow-up email to sec-announce@bytecodealliance.org describing the security release. Other communication channels can also be used to inform users about the security release.
By following these steps, you can effectively manage and resolve security issues for your open source project, ensuring timely communication and collaboration while maintaining the integrity and security of your software.
## References
- [Vulnerability Response Runbook](https://github.com/bytecodealliance/rfcs/blob/main/accepted/vulnerability-response-runbook.md)
- [Wasmtime Security Vulnerability Runbook](https://docs.wasmtime.dev/security-vulnerability-runbook.html)

View File

@ -30,4 +30,4 @@ Before reporting an issue, particularly one related to crashing, consult [the ch
Upon receiving an issue, thoroughly review [the cheat sheet](https://github.com/bytecodealliance/rfcs/blob/main/accepted/what-is-considered-a-security-bug.md#cheat-sheet-is-this-bug-considered-a-security-vulnerability) to assess and _Report a security vulnerability_ if the issue is indeed a security vulnerability.
Once a security issue is confirmed, please refer to [the runbook](https://github.com/bytecodealliance/rfcs/blob/main/accepted/vulnerability-response-runbook.md) for the subsequent steps to take.
Once a security issue is confirmed, please refer to [the runbook](./security_issue_runbook.md) for the subsequent steps to take.

View File

@ -596,6 +596,7 @@ main(int argc, char *argv[])
wasm_module_inst_t wasm_module_inst = NULL;
RunningMode running_mode = 0;
RuntimeInitArgs init_args;
struct InstantiationArgs2 *inst_args;
char error_buf[128] = { 0 };
#if WASM_ENABLE_LOG != 0
int log_verbose_level = 2;
@ -949,10 +950,20 @@ main(int argc, char *argv[])
libc_wasi_init(wasm_module, argc, argv, &wasi_parse_ctx);
#endif
if (!wasm_runtime_instantiation_args_create(&inst_args)) {
printf("failed to create instantiate args\n");
goto fail3;
}
wasm_runtime_instantiation_args_set_default_stack_size(inst_args,
stack_size);
wasm_runtime_instantiation_args_set_host_managed_heap_size(inst_args,
heap_size);
/* instantiate the module */
if (!(wasm_module_inst =
wasm_runtime_instantiate(wasm_module, stack_size, heap_size,
error_buf, sizeof(error_buf)))) {
wasm_module_inst = wasm_runtime_instantiate_ex2(
wasm_module, inst_args, error_buf, sizeof(error_buf));
wasm_runtime_instantiation_args_destroy(inst_args);
if (!wasm_module_inst) {
printf("%s\n", error_buf);
goto fail3;
}

View File

@ -58,6 +58,7 @@ LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
option.enable_simd = true;
option.enable_ref_types = true;
option.enable_gc = true;
option.aux_stack_frame_type = AOT_STACK_FRAME_TYPE_STANDARD;
comp_data =
aot_create_comp_data(module, option.target_arch, option.enable_gc);

View File

@ -96,7 +96,7 @@
"argument": "",
"expected return": {
"ret code": 255,
"stdout content": "WASM module load failed: END opcode expected",
"stdout content": "WASM module load failed: unexpected end opcodes from unbalanced control flow structures",
"description": "no sanitizer 'Heap Buffer Overflow'"
}
},
@ -979,7 +979,7 @@
"argument": "",
"expected return": {
"ret code": 255,
"stdout content": "WASM module load failed: unexpected end of section or function",
"stdout content": "WASM module load failed: section size mismatch: function body END opcode expected",
"description": "no 'Heap out of bound read of size 1 in wasm_loader_prepare_bytecode function'"
}
},

View File

@ -172,6 +172,7 @@ def test_case(
clean_up_flag=True,
verbose_flag=True,
gc_flag=False,
extended_const_flag=False,
memory64_flag=False,
multi_memory_flag=False,
qemu_flag=False,
@ -229,6 +230,9 @@ def test_case(
if gc_flag:
CMD.append("--gc")
if extended_const_flag:
CMD.append("--extended-const")
if memory64_flag:
CMD.append("--memory64")
@ -304,6 +308,7 @@ def test_suite(
clean_up_flag=True,
verbose_flag=True,
gc_flag=False,
extended_const_flag=False,
memory64_flag=False,
multi_memory_flag=False,
parl_flag=False,
@ -385,6 +390,7 @@ def test_suite(
clean_up_flag,
verbose_flag,
gc_flag,
extended_const_flag,
memory64_flag,
multi_memory_flag,
qemu_flag,
@ -428,6 +434,7 @@ def test_suite(
clean_up_flag,
verbose_flag,
gc_flag,
extended_const_flag,
memory64_flag,
multi_memory_flag,
qemu_flag,
@ -561,6 +568,13 @@ def main():
dest="gc_flag",
help="Running with GC feature",
)
parser.add_argument(
"--enable-extended-const",
action="store_true",
default=False,
dest="extended_const_flag",
help="Running with extended const expression feature",
)
parser.add_argument(
"--memory64",
action="store_true",
@ -619,6 +633,7 @@ def main():
options.clean_up_flag,
options.verbose_flag,
options.gc_flag,
options.extended_const_flag,
options.memory64_flag,
options.multi_memory_flag,
options.parl_flag,
@ -648,6 +663,7 @@ def main():
options.clean_up_flag,
options.verbose_flag,
options.gc_flag,
options.extended_const_flag,
options.memory64_flag,
options.multi_memory_flag,
options.qemu_flag,

View File

@ -0,0 +1,506 @@
diff --git a/test/core/elem.wast b/test/core/elem.wast
index 92dab52..3954bca 100644
--- a/test/core/elem.wast
+++ b/test/core/elem.wast
@@ -571,6 +571,7 @@
;; Element sections across multiple modules change the same table
+(;
(module $module1
(type $out-i32 (func (result i32)))
(table (export "shared-table") 10 funcref)
@@ -620,7 +621,7 @@
(assert_return (invoke $module1 "call-7") (i32.const 67))
(assert_return (invoke $module1 "call-8") (i32.const 69))
(assert_return (invoke $module1 "call-9") (i32.const 70))
-
+;)
;; Element segments must match element type of table
(assert_invalid
@@ -659,24 +660,30 @@
(func (export "set") (param $i i32) (param $x externref)
(table.set $t (local.get $i) (local.get $x))))
-(register "exporter" $m)
+;; (register "exporter" $m)
-(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern))
-(assert_return (invoke $m "get" (i32.const 1)) (ref.null extern))
+;; (assert_return (invoke $m "get" (i32.const 0)) (ref.null extern))
+;; (assert_return (invoke $m "get" (i32.const 1)) (ref.null extern))
+(assert_return (invoke "get" (i32.const 0)) (ref.null extern))
+(assert_return (invoke "get" (i32.const 1)) (ref.null extern))
-(assert_return (invoke $m "set" (i32.const 0) (ref.extern 42)))
-(assert_return (invoke $m "set" (i32.const 1) (ref.extern 137)))
-
-(assert_return (invoke $m "get" (i32.const 0)) (ref.extern 42))
-(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137))
+;; (assert_return (invoke $m "set" (i32.const 0) (ref.extern 42)))
+;; (assert_return (invoke $m "set" (i32.const 1) (ref.extern 137)))
+(assert_return (invoke "set" (i32.const 0) (ref.extern 42)))
+(assert_return (invoke "set" (i32.const 1) (ref.extern 137)))
+;; (assert_return (invoke $m "get" (i32.const 0)) (ref.extern 42))
+;; (assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137))
+(assert_return (invoke "get" (i32.const 0)) (ref.extern 42))
+(assert_return (invoke "get" (i32.const 1)) (ref.extern 137))
+(;
(module
(import "exporter" "table" (table $t 2 externref))
(elem (i32.const 0) externref (ref.null extern)))
(assert_return (invoke $m "get" (i32.const 0)) (ref.null extern))
(assert_return (invoke $m "get" (i32.const 1)) (ref.extern 137))
-
+;)
;; Initializing a table with imported funcref global
(module $module4
@@ -686,6 +693,7 @@
(global (export "f") funcref (ref.func 0))
)
+(;
(register "module4" $module4)
(module
@@ -699,6 +707,7 @@
)
(assert_return (invoke "call_imported_elem") (i32.const 42))
+;)
;; Extended contant expressions
diff --git a/test/core/ref_func.wast b/test/core/ref_func.wast
index adb5cb7..6396013 100644
--- a/test/core/ref_func.wast
+++ b/test/core/ref_func.wast
@@ -4,7 +4,7 @@
(register "M")
(module
- (func $f (import "M" "f") (param i32) (result i32))
+ (func $f (param $x i32) (result i32) (local.get $x))
(func $g (param $x i32) (result i32)
(i32.add (local.get $x) (i32.const 1))
)
diff --git a/test/core/table_copy.wast b/test/core/table_copy.wast
index 380e84e..59230cf 100644
--- a/test/core/table_copy.wast
+++ b/test/core/table_copy.wast
@@ -14,11 +14,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -106,11 +106,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -198,11 +198,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -290,11 +290,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -382,11 +382,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -474,11 +474,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -566,11 +566,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -658,11 +658,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -750,11 +750,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -842,11 +842,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -934,11 +934,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -1026,11 +1026,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -1118,11 +1118,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -1210,11 +1210,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -1302,11 +1302,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -1394,11 +1394,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -1486,11 +1486,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -1578,11 +1578,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
diff --git a/test/core/table_init.wast b/test/core/table_init.wast
index 0b2d26f..3c595e5 100644
--- a/test/core/table_init.wast
+++ b/test/core/table_init.wast
@@ -14,11 +14,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -72,11 +72,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -130,11 +130,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t0) (i32.const 2) func 3 1 4 1)
@@ -196,11 +196,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -254,11 +254,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)
@@ -312,11 +312,11 @@
(module
(type (func (result i32))) ;; type #0
- (import "a" "ef0" (func (result i32))) ;; index 0
- (import "a" "ef1" (func (result i32)))
- (import "a" "ef2" (func (result i32)))
- (import "a" "ef3" (func (result i32)))
- (import "a" "ef4" (func (result i32))) ;; index 4
+ (func (result i32) (i32.const 0)) ;; index 0
+ (func (result i32) (i32.const 1))
+ (func (result i32) (i32.const 2))
+ (func (result i32) (i32.const 3))
+ (func (result i32) (i32.const 4)) ;; index 4
(table $t0 30 30 funcref)
(table $t1 30 30 funcref)
(elem (table $t1) (i32.const 2) func 3 1 4 1)

View File

@ -336,6 +336,9 @@ parser.add_argument('--multi-thread', default=False, action='store_true',
parser.add_argument('--gc', default=False, action='store_true',
help='Test with GC')
parser.add_argument('--extended-const', action='store_true',
help='Enable extended const expression feature')
parser.add_argument('--memory64', default=False, action='store_true',
help='Test with Memory64')
@ -1112,6 +1115,8 @@ def compile_wast_to_wasm(form, wast_tempfile, wasm_tempfile, opts):
cmd = [opts.wast2wasm, "--enable-memory64", "--no-check", wast_tempfile, "-o", wasm_tempfile ]
elif opts.multi_memory:
cmd = [opts.wast2wasm, "--enable-multi-memory", "--no-check", wast_tempfile, "-o", wasm_tempfile ]
elif opts.extended_const:
cmd = [opts.wast2wasm, "--enable-extended-const", "--no-check", wast_tempfile, "-o", wasm_tempfile ]
else:
# `--enable-multi-memory` for a case in memory.wast but doesn't require runtime support
cmd = [opts.wast2wasm, "--enable-multi-memory", "--enable-threads", "--no-check",
@ -1155,6 +1160,9 @@ def compile_wasm_to_aot(wasm_tempfile, aot_tempfile, runner, opts, r, output = '
cmd.append("--enable-gc")
cmd.append("--enable-tail-call")
if opts.extended_const:
cmd.append("--enable-extended-const")
if output == 'object':
cmd.append("--format=object")
elif output == 'ir':

View File

@ -41,6 +41,7 @@ function help()
echo "-j set the platform to test"
echo "-T set sanitizer to use in tests(ubsan|tsan|asan|posan)"
echo "-A use the specified wamrc command instead of building it"
echo "-N enable extended const expression feature"
echo "-r [requirement name] [N [N ...]] specify a requirement name followed by one or more"
echo " subrequirement IDs, if no subrequirement is specificed,"
echo " it will run all subrequirements. When this optin is used,"
@ -59,6 +60,7 @@ ENABLE_MULTI_THREAD=0
COLLECT_CODE_COVERAGE=0
ENABLE_SIMD=0
ENABLE_GC=0
ENABLE_EXTENDED_CONST_EXPR=0
ENABLE_MEMORY64=0
ENABLE_MULTI_MEMORY=0
ENABLE_XIP=0
@ -87,7 +89,7 @@ REQUIREMENT_NAME=""
# Initialize an empty array for subrequirement IDs
SUBREQUIREMENT_IDS=()
while getopts ":s:cabgvt:m:MCpSXexwWEPGQF:j:T:r:A:" opt
while getopts ":s:cabgvt:m:MCpSXexwWEPGQF:j:T:r:A:N" opt
do
OPT_PARSED="TRUE"
case $opt in
@ -191,6 +193,10 @@ do
echo "enable GC feature"
ENABLE_GC=1
;;
N)
echo "enable extended const expression feature"
ENABLE_EXTENDED_CONST_EXPR=1
;;
P)
PARALLELISM=1
;;
@ -485,6 +491,17 @@ function spec_test()
# (func $f (param (ref null $t)) (result funcref) (local.get 0))
#
compile_reference_interpreter
elif [[ ${ENABLE_EXTENDED_CONST_EXPR} == 1 ]]; then
echo "checkout spec for extended const expression proposal"
git clone -b main --single-branch https://github.com/WebAssembly/extended-const.git spec
pushd spec
# Jan 14, 2025. README.md: Add note that this proposal is done (#20)
git reset --hard 8d4f6aa2b00a8e7c0174410028625c6a176db8a1
# ignore import table cases
git apply --ignore-whitespace ../../spec-test-script/extended_const.patch || exit 1
elif [[ ${ENABLE_MEMORY64} == 1 ]]; then
echo "checkout spec for memory64 proposal"
@ -587,6 +604,10 @@ function spec_test()
ARGS_FOR_SPEC_TEST+="--gc "
fi
if [[ ${ENABLE_EXTENDED_CONST_EXPR} == 1 ]]; then
ARGS_FOR_SPEC_TEST+="--enable-extended-const "
fi
if [[ 1 == ${ENABLE_MEMORY64} ]]; then
ARGS_FOR_SPEC_TEST+="--memory64 "
fi
@ -832,6 +853,7 @@ function build_wamrc()
&& cmake .. \
-DCOLLECT_CODE_COVERAGE=${COLLECT_CODE_COVERAGE} \
-DWAMR_BUILD_SHRUNK_MEMORY=0 \
-DWAMR_BUILD_EXTENDED_CONST_EXPR=${ENABLE_EXTENDED_CONST_EXPR} \
&& make -j 4
}
@ -1023,6 +1045,10 @@ function trigger()
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_TAIL_CALL=1"
fi
if [[ ${ENABLE_EXTENDED_CONST_EXPR} == 1 ]]; then
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_EXTENDED_CONST_EXPR=1"
fi
if [[ ${ENABLE_DEBUG_VERSION} == 1 ]]; then
EXTRA_COMPILE_FLAGS+=" -DCMAKE_BUILD_TYPE=Debug"
fi

View File

@ -53,6 +53,7 @@ add_definitions(-DWASM_ENABLE_PERF_PROFILING=1)
add_definitions(-DWASM_ENABLE_LOAD_CUSTOM_SECTION=1)
add_definitions(-DWASM_ENABLE_MODULE_INST_CONTEXT=1)
add_definitions(-DWASM_ENABLE_MEMORY64=1)
add_definitions(-DWASM_ENABLE_EXTENDED_CONST_EXPR=1)
add_definitions(-DWASM_ENABLE_GC=1)

View File

@ -423,6 +423,7 @@ main(int argc, char *argv[])
option.enable_bulk_memory = true;
option.enable_ref_types = true;
option.enable_gc = false;
option.enable_extended_const = false;
aot_call_stack_features_init_default(&option.call_stack_features);
/* Process options */
@ -536,6 +537,9 @@ main(int argc, char *argv[])
else if (!strcmp(argv[0], "--disable-aux-stack-check")) {
option.enable_aux_stack_check = false;
}
else if (!strcmp(argv[0], "--enable-extended-const")) {
option.enable_extended_const = true;
}
else if (!strcmp(argv[0], "--enable-dump-call-stack")) {
option.aux_stack_frame_type = AOT_STACK_FRAME_TYPE_STANDARD;
}