summaryrefslogtreecommitdiff
path: root/deps/v8/third_party/wasm-api
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2019-08-16 11:32:46 +0200
committerMichaël Zasso <targos@protonmail.com>2019-08-19 09:25:23 +0200
commite31f0a7d25668d3c1531294d2ef44a9f3bde4ef4 (patch)
tree6c6bed9804be9df6162b2483f0a56f371f66464d /deps/v8/third_party/wasm-api
parentec16fdae540adaf710b1a86c620170b2880088f0 (diff)
downloadandroid-node-v8-e31f0a7d25668d3c1531294d2ef44a9f3bde4ef4.tar.gz
android-node-v8-e31f0a7d25668d3c1531294d2ef44a9f3bde4ef4.tar.bz2
android-node-v8-e31f0a7d25668d3c1531294d2ef44a9f3bde4ef4.zip
deps: update V8 to 7.7.299.4
PR-URL: https://github.com/nodejs/node/pull/28918 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'deps/v8/third_party/wasm-api')
-rw-r--r--deps/v8/third_party/wasm-api/LICENSE202
-rw-r--r--deps/v8/third_party/wasm-api/OWNERS2
-rw-r--r--deps/v8/third_party/wasm-api/README.v817
-rw-r--r--deps/v8/third_party/wasm-api/example/callback.c167
-rw-r--r--deps/v8/third_party/wasm-api/example/callback.cc145
-rw-r--r--deps/v8/third_party/wasm-api/example/callback.wasmbin0 -> 102 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/callback.wat10
-rw-r--r--deps/v8/third_party/wasm-api/example/finalize.c75
-rw-r--r--deps/v8/third_party/wasm-api/example/finalize.cc70
-rw-r--r--deps/v8/third_party/wasm-api/example/finalize.wasmbin0 -> 75 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/finalize.wat5
-rw-r--r--deps/v8/third_party/wasm-api/example/global.c222
-rw-r--r--deps/v8/third_party/wasm-api/example/global.cc193
-rw-r--r--deps/v8/third_party/wasm-api/example/global.wasmbin0 -> 576 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/global.wat27
-rw-r--r--deps/v8/third_party/wasm-api/example/hello.c107
-rw-r--r--deps/v8/third_party/wasm-api/example/hello.cc91
-rw-r--r--deps/v8/third_party/wasm-api/example/hello.wasmbin0 -> 71 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/hello.wat4
-rw-r--r--deps/v8/third_party/wasm-api/example/memory.c217
-rw-r--r--deps/v8/third_party/wasm-api/example/memory.cc169
-rw-r--r--deps/v8/third_party/wasm-api/example/memory.wasmbin0 -> 146 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/memory.wat11
-rw-r--r--deps/v8/third_party/wasm-api/example/reflect.c164
-rw-r--r--deps/v8/third_party/wasm-api/example/reflect.cc138
-rw-r--r--deps/v8/third_party/wasm-api/example/reflect.wasmbin0 -> 124 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/reflect.wat6
-rw-r--r--deps/v8/third_party/wasm-api/example/serialize.c122
-rw-r--r--deps/v8/third_party/wasm-api/example/serialize.cc103
-rw-r--r--deps/v8/third_party/wasm-api/example/serialize.wasmbin0 -> 71 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/serialize.wat4
-rw-r--r--deps/v8/third_party/wasm-api/example/table.c208
-rw-r--r--deps/v8/third_party/wasm-api/example/table.cc189
-rw-r--r--deps/v8/third_party/wasm-api/example/table.wasmbin0 -> 139 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/table.wat12
-rw-r--r--deps/v8/third_party/wasm-api/example/threads.c152
-rw-r--r--deps/v8/third_party/wasm-api/example/threads.cc124
-rw-r--r--deps/v8/third_party/wasm-api/example/threads.wasmbin0 -> 84 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/threads.wat5
-rw-r--r--deps/v8/third_party/wasm-api/example/trap.c121
-rw-r--r--deps/v8/third_party/wasm-api/example/trap.cc100
-rw-r--r--deps/v8/third_party/wasm-api/example/trap.wasmbin0 -> 105 bytes
-rw-r--r--deps/v8/third_party/wasm-api/example/trap.wat5
-rw-r--r--deps/v8/third_party/wasm-api/wasm.h677
-rw-r--r--deps/v8/third_party/wasm-api/wasm.hh770
45 files changed, 4634 insertions, 0 deletions
diff --git a/deps/v8/third_party/wasm-api/LICENSE b/deps/v8/third_party/wasm-api/LICENSE
new file mode 100644
index 0000000000..8f71f43fee
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/LICENSE
@@ -0,0 +1,202 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
diff --git a/deps/v8/third_party/wasm-api/OWNERS b/deps/v8/third_party/wasm-api/OWNERS
new file mode 100644
index 0000000000..596440f532
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/OWNERS
@@ -0,0 +1,2 @@
+jkummerow@chromium.org
+mstarzinger@chromium.org
diff --git a/deps/v8/third_party/wasm-api/README.v8 b/deps/v8/third_party/wasm-api/README.v8
new file mode 100644
index 0000000000..ea957620b0
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/README.v8
@@ -0,0 +1,17 @@
+Name: Wasm C/C++ API
+Short Name: wasm-c-api
+URL: https://github.com/WebAssembly/wasm-c-api/
+Version: 0
+Revision: 5c742b048f7766a0c00be3a7af23fb71ba816026
+Date: 2019-03-18
+License: Apache 2.0
+License File: LICENSE
+Security Critical: yes
+
+Description:
+Provides a "black box" API for embedding a Wasm engine in C/C++ applications.
+
+Local modifications:
+None.
+The contents of the upstream "include/" directory are directly in here.
+The upstream "example/" directory is copied as-is.
diff --git a/deps/v8/third_party/wasm-api/example/callback.c b/deps/v8/third_party/wasm-api/example/callback.c
new file mode 100644
index 0000000000..f3b9018594
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/callback.c
@@ -0,0 +1,167 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "wasm.h"
+
+#define own
+
+// Print a Wasm value
+void wasm_val_print(wasm_val_t val) {
+ switch (val.kind) {
+ case WASM_I32: {
+ printf("%" PRIu32, val.of.i32);
+ } break;
+ case WASM_I64: {
+ printf("%" PRIu64, val.of.i64);
+ } break;
+ case WASM_F32: {
+ printf("%f", val.of.f32);
+ } break;
+ case WASM_F64: {
+ printf("%g", val.of.f64);
+ } break;
+ case WASM_ANYREF:
+ case WASM_FUNCREF: {
+ if (val.of.ref == NULL) {
+ printf("null");
+ } else {
+ printf("ref(%p)", val.of.ref);
+ }
+ } break;
+ }
+}
+
+// A function to be called from Wasm code.
+own wasm_trap_t* print_callback(
+ const wasm_val_t args[], wasm_val_t results[]
+) {
+ printf("Calling back...\n> ");
+ wasm_val_print(args[0]);
+ printf("\n");
+
+ wasm_val_copy(&results[0], &args[0]);
+ return NULL;
+}
+
+
+// A function closure.
+own wasm_trap_t* closure_callback(
+ void* env, const wasm_val_t args[], wasm_val_t results[]
+) {
+ int i = *(int*)env;
+ printf("Calling back closure...\n");
+ printf("> %d\n", i);
+
+ results[0].kind = WASM_I32;
+ results[0].of.i32 = (int32_t)i;
+ return NULL;
+}
+
+
+int main(int argc, const char* argv[]) {
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t* engine = wasm_engine_new();
+ wasm_store_t* store = wasm_store_new(engine);
+
+ // Load binary.
+ printf("Loading binary...\n");
+ FILE* file = fopen("callback.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile.
+ printf("Compiling module...\n");
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ // Create external print functions.
+ printf("Creating callback...\n");
+ own wasm_functype_t* print_type = wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32());
+ own wasm_func_t* print_func = wasm_func_new(store, print_type, print_callback);
+
+ int i = 42;
+ own wasm_functype_t* closure_type = wasm_functype_new_0_1(wasm_valtype_new_i32());
+ own wasm_func_t* closure_func = wasm_func_new_with_env(store, closure_type, closure_callback, &i, NULL);
+
+ wasm_functype_delete(print_type);
+ wasm_functype_delete(closure_type);
+
+ // Instantiate.
+ printf("Instantiating module...\n");
+ const wasm_extern_t* imports[] = {
+ wasm_func_as_extern(print_func), wasm_func_as_extern(closure_func)
+ };
+ own wasm_instance_t* instance = wasm_instance_new(store, module, imports);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ return 1;
+ }
+
+ wasm_func_delete(print_func);
+ wasm_func_delete(closure_func);
+
+ // Extract export.
+ printf("Extracting export...\n");
+ own wasm_extern_vec_t exports;
+ wasm_instance_exports(instance, &exports);
+ if (exports.size == 0) {
+ printf("> Error accessing exports!\n");
+ return 1;
+ }
+ const wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]);
+ if (run_func == NULL) {
+ printf("> Error accessing export!\n");
+ return 1;
+ }
+
+ wasm_module_delete(module);
+ wasm_instance_delete(instance);
+
+ // Call.
+ printf("Calling export...\n");
+ wasm_val_t args[2];
+ args[0].kind = WASM_I32;
+ args[0].of.i32 = 3;
+ args[1].kind = WASM_I32;
+ args[1].of.i32 = 4;
+ wasm_val_t results[1];
+ if (wasm_func_call(run_func, args, results)) {
+ printf("> Error calling function!\n");
+ return 1;
+ }
+
+ wasm_extern_vec_delete(&exports);
+
+ // Print result.
+ printf("Printing result...\n");
+ printf("> %u\n", results[0].of.i32);
+
+ // Shut down.
+ printf("Shutting down...\n");
+ wasm_store_delete(store);
+ wasm_engine_delete(engine);
+
+ // All done.
+ printf("Done.\n");
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/callback.cc b/deps/v8/third_party/wasm-api/example/callback.cc
new file mode 100644
index 0000000000..a9ee9aa919
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/callback.cc
@@ -0,0 +1,145 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <cinttypes>
+
+#include "wasm.hh"
+
+// Print a Wasm value
+auto operator<<(std::ostream& out, const wasm::Val& val) -> std::ostream& {
+ switch (val.kind()) {
+ case wasm::I32: {
+ out << val.i32();
+ } break;
+ case wasm::I64: {
+ out << val.i64();
+ } break;
+ case wasm::F32: {
+ out << val.f32();
+ } break;
+ case wasm::F64: {
+ out << val.f64();
+ } break;
+ case wasm::ANYREF:
+ case wasm::FUNCREF: {
+ if (val.ref() == nullptr) {
+ out << "null";
+ } else {
+ out << "ref(" << val.ref() << ")";
+ }
+ } break;
+ }
+ return out;
+}
+
+// A function to be called from Wasm code.
+auto print_callback(
+ const wasm::Val args[], wasm::Val results[]
+) -> wasm::own<wasm::Trap*> {
+ std::cout << "Calling back..." << std::endl << "> " << args[0] << std::endl;
+ results[0] = args[0].copy();
+ return nullptr;
+}
+
+
+// A function closure.
+auto closure_callback(
+ void* env, const wasm::Val args[], wasm::Val results[]
+) -> wasm::own<wasm::Trap*> {
+ auto i = *reinterpret_cast<int*>(env);
+ std::cout << "Calling back closure..." << std::endl;
+ std::cout << "> " << i << std::endl;
+ results[0] = wasm::Val::i32(static_cast<int32_t>(i));
+ return nullptr;
+}
+
+
+void run() {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+ auto store_ = wasm::Store::make(engine.get());
+ auto store = store_.get();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("callback.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return;
+ }
+
+ // Compile.
+ std::cout << "Compiling module..." << std::endl;
+ auto module = wasm::Module::make(store, binary);
+ if (!module) {
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Create external print functions.
+ std::cout << "Creating callback..." << std::endl;
+ auto print_type = wasm::FuncType::make(
+ wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)),
+ wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32))
+ );
+ auto print_func = wasm::Func::make(store, print_type.get(), print_callback);
+
+ // Creating closure.
+ std::cout << "Creating closure..." << std::endl;
+ int i = 42;
+ auto closure_type = wasm::FuncType::make(
+ wasm::vec<wasm::ValType*>::make(),
+ wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32))
+ );
+ auto closure_func = wasm::Func::make(store, closure_type.get(), closure_callback, &i);
+
+ // Instantiate.
+ std::cout << "Instantiating module..." << std::endl;
+ wasm::Extern* imports[] = {print_func.get(), closure_func.get()};
+ auto instance = wasm::Instance::make(store, module.get(), imports);
+ if (!instance) {
+ std::cout << "> Error instantiating module!" << std::endl;
+ return;
+ }
+
+ // Extract export.
+ std::cout << "Extracting export..." << std::endl;
+ auto exports = instance->exports();
+ if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) {
+ std::cout << "> Error accessing export!" << std::endl;
+ return;
+ }
+ auto run_func = exports[0]->func();
+
+ // Call.
+ std::cout << "Calling export..." << std::endl;
+ wasm::Val args[] = {wasm::Val::i32(3), wasm::Val::i32(4)};
+ wasm::Val results[1];
+ if (run_func->call(args, results)) {
+ std::cout << "> Error calling function!" << std::endl;
+ return;
+ }
+
+ // Print result.
+ std::cout << "Printing result..." << std::endl;
+ std::cout << "> " << results[0].i32() << std::endl;
+
+ // Shut down.
+ std::cout << "Shutting down..." << std::endl;
+}
+
+
+int main(int argc, const char* argv[]) {
+ run();
+ std::cout << "Done." << std::endl;
+ return 0;
+}
+
diff --git a/deps/v8/third_party/wasm-api/example/callback.wasm b/deps/v8/third_party/wasm-api/example/callback.wasm
new file mode 100644
index 0000000000..7e00b58014
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/callback.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/callback.wat b/deps/v8/third_party/wasm-api/example/callback.wat
new file mode 100644
index 0000000000..d86195f51d
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/callback.wat
@@ -0,0 +1,10 @@
+(module
+ (func $print (import "" "print") (param i32) (result i32))
+ (func $closure (import "" "closure") (result i32))
+ (func (export "run") (param $x i32) (param $y i32) (result i32)
+ (i32.add
+ (call $print (i32.add (local.get $x) (local.get $y)))
+ (call $closure)
+ )
+ )
+)
diff --git a/deps/v8/third_party/wasm-api/example/finalize.c b/deps/v8/third_party/wasm-api/example/finalize.c
new file mode 100644
index 0000000000..6841617262
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/finalize.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "wasm.h"
+
+#define own
+
+const int iterations = 100000;
+
+void finalize(void* data) {
+ int i = (int)data;
+ if (i % (iterations / 10) == 0) printf("Finalizing #%d...\n", i);
+}
+
+int main(int argc, const char* argv[]) {
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t* engine = wasm_engine_new();
+ wasm_store_t* store = wasm_store_new(engine);
+
+ // Load binary.
+ printf("Loading binary...\n");
+ FILE* file = fopen("finalize.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile.
+ printf("Compiling module...\n");
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ // Instantiate.
+ printf("Instantiating modules...\n");
+ for (int i = 0; i <= iterations; ++i) {
+ if (i % (iterations / 10) == 0) printf("%d\n", i);
+ own wasm_instance_t* instance = wasm_instance_new(store, module, NULL);
+ if (!instance) {
+ printf("> Error instantiating module %d!\n", i);
+ return 1;
+ }
+ void* data = (void*)(intptr_t)i;
+ wasm_instance_set_host_info_with_finalizer(instance, data, &finalize);
+ wasm_instance_delete(instance);
+ }
+
+ wasm_module_delete(module);
+
+ // Shut down.
+ printf("Shutting down...\n");
+ wasm_store_delete(store);
+ wasm_engine_delete(engine);
+
+ // All done.
+ printf("Done.\n");
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/finalize.cc b/deps/v8/third_party/wasm-api/example/finalize.cc
new file mode 100644
index 0000000000..a354a2601d
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/finalize.cc
@@ -0,0 +1,70 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <cinttypes>
+
+#include "wasm.hh"
+
+
+const int iterations = 100000;
+
+void finalize(void* data) {
+ intptr_t i = reinterpret_cast<intptr_t>(data);
+ if (i % (iterations / 10) == 0) {
+ std::cout << "Finalizing #" << i << "..." << std::endl;
+ }
+}
+
+void run() {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+ auto store_ = wasm::Store::make(engine.get());
+ auto store = store_.get();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("finalize.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return;
+ }
+
+ // Compile.
+ std::cout << "Compiling module..." << std::endl;
+ auto module = wasm::Module::make(store, binary);
+ if (!module) {
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Instantiate.
+ std::cout << "Instantiating modules..." << std::endl;
+ for (int i = 0; i <= iterations; ++i) {
+ if (i % (iterations / 10) == 0) std::cout << i << std::endl;
+ auto instance = wasm::Instance::make(store, module.get(), nullptr);
+ if (!instance) {
+ std::cout << "> Error instantiating module " << i << "!" << std::endl;
+ return;
+ }
+ instance->set_host_info(reinterpret_cast<void*>(i), &finalize);
+ }
+
+ // Shut down.
+ std::cout << "Shutting down..." << std::endl;
+}
+
+
+int main(int argc, const char* argv[]) {
+ run();
+ std::cout << "Done." << std::endl;
+ return 0;
+}
+
diff --git a/deps/v8/third_party/wasm-api/example/finalize.wasm b/deps/v8/third_party/wasm-api/example/finalize.wasm
new file mode 100644
index 0000000000..74f9c56624
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/finalize.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/finalize.wat b/deps/v8/third_party/wasm-api/example/finalize.wat
new file mode 100644
index 0000000000..6237e734ac
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/finalize.wat
@@ -0,0 +1,5 @@
+(module
+ (func (export "f"))
+ (func (export "g"))
+ (func (export "h"))
+)
diff --git a/deps/v8/third_party/wasm-api/example/global.c b/deps/v8/third_party/wasm-api/example/global.c
new file mode 100644
index 0000000000..b82d86242e
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/global.c
@@ -0,0 +1,222 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "wasm.h"
+
+#define own
+
+wasm_global_t* get_export_global(const wasm_extern_vec_t* exports, size_t i) {
+ if (exports->size <= i || !wasm_extern_as_global(exports->data[i])) {
+ printf("> Error accessing global export %zu!\n", i);
+ exit(1);
+ }
+ return wasm_extern_as_global(exports->data[i]);
+}
+
+wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) {
+ if (exports->size <= i || !wasm_extern_as_func(exports->data[i])) {
+ printf("> Error accessing function export %zu!\n", i);
+ exit(1);
+ }
+ return wasm_extern_as_func(exports->data[i]);
+}
+
+
+#define check(val, type, expected) \
+ if (val.of.type != expected) { \
+ printf("> Error reading value\n"); \
+ exit(1); \
+ }
+
+#define check_global(global, type, expected) \
+ { \
+ wasm_val_t val; \
+ wasm_global_get(global, &val); \
+ check(val, type, expected); \
+ }
+
+#define check_call(func, type, expected) \
+ { \
+ wasm_val_t results[1]; \
+ wasm_func_call(func, NULL, results); \
+ check(results[0], type, expected); \
+ }
+
+
+int main(int argc, const char* argv[]) {
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t* engine = wasm_engine_new();
+ wasm_store_t* store = wasm_store_new(engine);
+
+ // Load binary.
+ printf("Loading binary...\n");
+ FILE* file = fopen("global.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile.
+ printf("Compiling module...\n");
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ // Create external globals.
+ printf("Creating globals...\n");
+ own wasm_globaltype_t* const_f32_type = wasm_globaltype_new(
+ wasm_valtype_new(WASM_F32), WASM_CONST);
+ own wasm_globaltype_t* const_i64_type = wasm_globaltype_new(
+ wasm_valtype_new(WASM_I64), WASM_CONST);
+ own wasm_globaltype_t* var_f32_type = wasm_globaltype_new(
+ wasm_valtype_new(WASM_F32), WASM_VAR);
+ own wasm_globaltype_t* var_i64_type = wasm_globaltype_new(
+ wasm_valtype_new(WASM_I64), WASM_VAR);
+
+ wasm_val_t val_f32_1 = {.kind = WASM_F32, .of = {.f32 = 1}};
+ own wasm_global_t* const_f32_import = wasm_global_new(store, const_f32_type, &val_f32_1);
+ wasm_val_t val_i64_2 = {.kind = WASM_I64, .of = {.i64 = 2}};
+ own wasm_global_t* const_i64_import = wasm_global_new(store, const_i64_type, &val_i64_2);
+ wasm_val_t val_f32_3 = {.kind = WASM_F32, .of = {.f32 = 3}};
+ own wasm_global_t* var_f32_import = wasm_global_new(store, var_f32_type, &val_f32_3);
+ wasm_val_t val_i64_4 = {.kind = WASM_I64, .of = {.i64 = 4}};
+ own wasm_global_t* var_i64_import = wasm_global_new(store, var_i64_type, &val_i64_4);
+
+ wasm_globaltype_delete(const_f32_type);
+ wasm_globaltype_delete(const_i64_type);
+ wasm_globaltype_delete(var_f32_type);
+ wasm_globaltype_delete(var_i64_type);
+
+ // Instantiate.
+ printf("Instantiating module...\n");
+ const wasm_extern_t* imports[] = {
+ wasm_global_as_extern(const_f32_import),
+ wasm_global_as_extern(const_i64_import),
+ wasm_global_as_extern(var_f32_import),
+ wasm_global_as_extern(var_i64_import)
+ };
+ own wasm_instance_t* instance = wasm_instance_new(store, module, imports);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ return 1;
+ }
+
+ wasm_module_delete(module);
+
+ // Extract export.
+ printf("Extracting exports...\n");
+ own wasm_extern_vec_t exports;
+ wasm_instance_exports(instance, &exports);
+ size_t i = 0;
+ wasm_global_t* const_f32_export = get_export_global(&exports, i++);
+ wasm_global_t* const_i64_export = get_export_global(&exports, i++);
+ wasm_global_t* var_f32_export = get_export_global(&exports, i++);
+ wasm_global_t* var_i64_export = get_export_global(&exports, i++);
+ wasm_func_t* get_const_f32_import = get_export_func(&exports, i++);
+ wasm_func_t* get_const_i64_import = get_export_func(&exports, i++);
+ wasm_func_t* get_var_f32_import = get_export_func(&exports, i++);
+ wasm_func_t* get_var_i64_import = get_export_func(&exports, i++);
+ wasm_func_t* get_const_f32_export = get_export_func(&exports, i++);
+ wasm_func_t* get_const_i64_export = get_export_func(&exports, i++);
+ wasm_func_t* get_var_f32_export = get_export_func(&exports, i++);
+ wasm_func_t* get_var_i64_export = get_export_func(&exports, i++);
+ wasm_func_t* set_var_f32_import = get_export_func(&exports, i++);
+ wasm_func_t* set_var_i64_import = get_export_func(&exports, i++);
+ wasm_func_t* set_var_f32_export = get_export_func(&exports, i++);
+ wasm_func_t* set_var_i64_export = get_export_func(&exports, i++);
+
+ // Interact.
+ printf("Accessing globals...\n");
+
+ // Check initial values.
+ check_global(const_f32_import, f32, 1);
+ check_global(const_i64_import, i64, 2);
+ check_global(var_f32_import, f32, 3);
+ check_global(var_i64_import, i64, 4);
+ check_global(const_f32_export, f32, 5);
+ check_global(const_i64_export, i64, 6);
+ check_global(var_f32_export, f32, 7);
+ check_global(var_i64_export, i64, 8);
+
+ check_call(get_const_f32_import, f32, 1);
+ check_call(get_const_i64_import, i64, 2);
+ check_call(get_var_f32_import, f32, 3);
+ check_call(get_var_i64_import, i64, 4);
+ check_call(get_const_f32_export, f32, 5);
+ check_call(get_const_i64_export, i64, 6);
+ check_call(get_var_f32_export, f32, 7);
+ check_call(get_var_i64_export, i64, 8);
+
+ // Modify variables through API and check again.
+ wasm_val_t val33 = {.kind = WASM_F32, .of = {.f32 = 33}};
+ wasm_global_set(var_f32_import, &val33);
+ wasm_val_t val34 = {.kind = WASM_I64, .of = {.i64 = 34}};
+ wasm_global_set(var_i64_import, &val34);
+ wasm_val_t val37 = {.kind = WASM_F32, .of = {.f32 = 37}};
+ wasm_global_set(var_f32_export, &val37);
+ wasm_val_t val38 = {.kind = WASM_I64, .of = {.i64 = 38}};
+ wasm_global_set(var_i64_export, &val38);
+
+ check_global(var_f32_import, f32, 33);
+ check_global(var_i64_import, i64, 34);
+ check_global(var_f32_export, f32, 37);
+ check_global(var_i64_export, i64, 38);
+
+ check_call(get_var_f32_import, f32, 33);
+ check_call(get_var_i64_import, i64, 34);
+ check_call(get_var_f32_export, f32, 37);
+ check_call(get_var_i64_export, i64, 38);
+
+ // Modify variables through calls and check again.
+ wasm_val_t args73[] = { {.kind = WASM_F32, .of = {.f32 = 73}} };
+ wasm_func_call(set_var_f32_import, args73, NULL);
+ wasm_val_t args74[] = { {.kind = WASM_I64, .of = {.i64 = 74}} };
+ wasm_func_call(set_var_i64_import, args74, NULL);
+ wasm_val_t args77[] = { {.kind = WASM_F32, .of = {.f32 = 77}} };
+ wasm_func_call(set_var_f32_export, args77, NULL);
+ wasm_val_t args78[] = { {.kind = WASM_I64, .of = {.i64 = 78}} };
+ wasm_func_call(set_var_i64_export, args78, NULL);
+
+ check_global(var_f32_import, f32, 73);
+ check_global(var_i64_import, i64, 74);
+ check_global(var_f32_export, f32, 77);
+ check_global(var_i64_export, i64, 78);
+
+ check_call(get_var_f32_import, f32, 73);
+ check_call(get_var_i64_import, i64, 74);
+ check_call(get_var_f32_export, f32, 77);
+ check_call(get_var_i64_export, i64, 78);
+
+ wasm_global_delete(const_f32_import);
+ wasm_global_delete(const_i64_import);
+ wasm_global_delete(var_f32_import);
+ wasm_global_delete(var_i64_import);
+ wasm_extern_vec_delete(&exports);
+ wasm_instance_delete(instance);
+
+ // Shut down.
+ printf("Shutting down...\n");
+ wasm_store_delete(store);
+ wasm_engine_delete(engine);
+
+ // All done.
+ printf("Done.\n");
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/global.cc b/deps/v8/third_party/wasm-api/example/global.cc
new file mode 100644
index 0000000000..75a2513c82
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/global.cc
@@ -0,0 +1,193 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <cinttypes>
+
+#include "wasm.hh"
+
+
+auto get_export_global(wasm::vec<wasm::Extern*>& exports, size_t i) -> wasm::Global* {
+ if (exports.size() <= i || !exports[i]->global()) {
+ std::cout << "> Error accessing global export " << i << "!" << std::endl;
+ exit(1);
+ }
+ return exports[i]->global();
+}
+
+auto get_export_func(const wasm::vec<wasm::Extern*>& exports, size_t i) -> const wasm::Func* {
+ if (exports.size() <= i || !exports[i]->func()) {
+ std::cout << "> Error accessing function export " << i << "!" << std::endl;
+ exit(1);
+ }
+ return exports[i]->func();
+}
+
+template<class T, class U>
+void check(T actual, U expected) {
+ if (actual != expected) {
+ std::cout << "> Error reading value, expected " << expected << ", got " << actual << std::endl;
+ exit(1);
+ }
+}
+
+auto call(const wasm::Func* func) -> wasm::Val {
+ wasm::Val results[1];
+ if (func->call(nullptr, results)) {
+ std::cout << "> Error calling function!" << std::endl;
+ exit(1);
+ }
+ return results[0].copy();
+}
+
+void call(const wasm::Func* func, wasm::Val&& arg) {
+ wasm::Val args[1] = {std::move(arg)};
+ if (func->call(args)) {
+ std::cout << "> Error calling function!" << std::endl;
+ exit(1);
+ }
+}
+
+
+void run() {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+ auto store_ = wasm::Store::make(engine.get());
+ auto store = store_.get();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("global.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return;
+ }
+
+ // Compile.
+ std::cout << "Compiling module..." << std::endl;
+ auto module = wasm::Module::make(store, binary);
+ if (!module) {
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Create external globals.
+ std::cout << "Creating globals..." << std::endl;
+ auto const_f32_type = wasm::GlobalType::make(
+ wasm::ValType::make(wasm::F32), wasm::CONST);
+ auto const_i64_type = wasm::GlobalType::make(
+ wasm::ValType::make(wasm::I64), wasm::CONST);
+ auto var_f32_type = wasm::GlobalType::make(
+ wasm::ValType::make(wasm::F32), wasm::VAR);
+ auto var_i64_type = wasm::GlobalType::make(
+ wasm::ValType::make(wasm::I64), wasm::VAR);
+ auto const_f32_import = wasm::Global::make(store, const_f32_type.get(), wasm::Val::f32(1));
+ auto const_i64_import = wasm::Global::make(store, const_i64_type.get(), wasm::Val::i64(2));
+ auto var_f32_import = wasm::Global::make(store, var_f32_type.get(), wasm::Val::f32(3));
+ auto var_i64_import = wasm::Global::make(store, var_i64_type.get(), wasm::Val::i64(4));
+
+ // Instantiate.
+ std::cout << "Instantiating module..." << std::endl;
+ wasm::Extern* imports[] = {
+ const_f32_import.get(), const_i64_import.get(),
+ var_f32_import.get(), var_i64_import.get()
+ };
+ auto instance = wasm::Instance::make(store, module.get(), imports);
+ if (!instance) {
+ std::cout << "> Error instantiating module!" << std::endl;
+ return;
+ }
+
+ // Extract export.
+ std::cout << "Extracting exports..." << std::endl;
+ auto exports = instance->exports();
+ size_t i = 0;
+ auto const_f32_export = get_export_global(exports, i++);
+ auto const_i64_export = get_export_global(exports, i++);
+ auto var_f32_export = get_export_global(exports, i++);
+ auto var_i64_export = get_export_global(exports, i++);
+ auto get_const_f32_import = get_export_func(exports, i++);
+ auto get_const_i64_import = get_export_func(exports, i++);
+ auto get_var_f32_import = get_export_func(exports, i++);
+ auto get_var_i64_import = get_export_func(exports, i++);
+ auto get_const_f32_export = get_export_func(exports, i++);
+ auto get_const_i64_export = get_export_func(exports, i++);
+ auto get_var_f32_export = get_export_func(exports, i++);
+ auto get_var_i64_export = get_export_func(exports, i++);
+ auto set_var_f32_import = get_export_func(exports, i++);
+ auto set_var_i64_import = get_export_func(exports, i++);
+ auto set_var_f32_export = get_export_func(exports, i++);
+ auto set_var_i64_export = get_export_func(exports, i++);
+
+ // Interact.
+ std::cout << "Accessing globals..." << std::endl;
+
+ // Check initial values.
+ check(const_f32_import->get().f32(), 1);
+ check(const_i64_import->get().i64(), 2);
+ check(var_f32_import->get().f32(), 3);
+ check(var_i64_import->get().i64(), 4);
+ check(const_f32_export->get().f32(), 5);
+ check(const_i64_export->get().i64(), 6);
+ check(var_f32_export->get().f32(), 7);
+ check(var_i64_export->get().i64(), 8);
+
+ check(call(get_const_f32_import).f32(), 1);
+ check(call(get_const_i64_import).i64(), 2);
+ check(call(get_var_f32_import).f32(), 3);
+ check(call(get_var_i64_import).i64(), 4);
+ check(call(get_const_f32_export).f32(), 5);
+ check(call(get_const_i64_export).i64(), 6);
+ check(call(get_var_f32_export).f32(), 7);
+ check(call(get_var_i64_export).i64(), 8);
+
+ // Modify variables through API and check again.
+ var_f32_import->set(wasm::Val::f32(33));
+ var_i64_import->set(wasm::Val::i64(34));
+ var_f32_export->set(wasm::Val::f32(37));
+ var_i64_export->set(wasm::Val::i64(38));
+
+ check(var_f32_import->get().f32(), 33);
+ check(var_i64_import->get().i64(), 34);
+ check(var_f32_export->get().f32(), 37);
+ check(var_i64_export->get().i64(), 38);
+
+ check(call(get_var_f32_import).f32(), 33);
+ check(call(get_var_i64_import).i64(), 34);
+ check(call(get_var_f32_export).f32(), 37);
+ check(call(get_var_i64_export).i64(), 38);
+
+ // Modify variables through calls and check again.
+ call(set_var_f32_import, wasm::Val::f32(73));
+ call(set_var_i64_import, wasm::Val::i64(74));
+ call(set_var_f32_export, wasm::Val::f32(77));
+ call(set_var_i64_export, wasm::Val::i64(78));
+
+ check(var_f32_import->get().f32(), 73);
+ check(var_i64_import->get().i64(), 74);
+ check(var_f32_export->get().f32(), 77);
+ check(var_i64_export->get().i64(), 78);
+
+ check(call(get_var_f32_import).f32(), 73);
+ check(call(get_var_i64_import).i64(), 74);
+ check(call(get_var_f32_export).f32(), 77);
+ check(call(get_var_i64_export).i64(), 78);
+
+ // Shut down.
+ std::cout << "Shutting down..." << std::endl;
+}
+
+
+int main(int argc, const char* argv[]) {
+ run();
+ std::cout << "Done." << std::endl;
+ return 0;
+}
+
diff --git a/deps/v8/third_party/wasm-api/example/global.wasm b/deps/v8/third_party/wasm-api/example/global.wasm
new file mode 100644
index 0000000000..0e76863278
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/global.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/global.wat b/deps/v8/third_party/wasm-api/example/global.wat
new file mode 100644
index 0000000000..dea085772b
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/global.wat
@@ -0,0 +1,27 @@
+(module
+ (global $f32_import (import "" "const f32") f32)
+ (global $i64_import (import "" "const i64") i64)
+ (global $mut_f32_import (import "" "var f32") (mut f32))
+ (global $mut_i64_import (import "" "var i64") (mut i64))
+
+ (global $f32_export (export "const f32") f32 (f32.const 5))
+ (global $i64_export (export "const i64") i64 (i64.const 6))
+ (global $mut_f32_export (export "var f32") (mut f32) (f32.const 7))
+ (global $mut_i64_export (export "var i64") (mut i64) (i64.const 8))
+
+ (func (export "get const f32 import") (result f32) (global.get $f32_import))
+ (func (export "get const i64 import") (result i64) (global.get $i64_import))
+ (func (export "get var f32 import") (result f32) (global.get $mut_f32_import))
+ (func (export "get var i64 import") (result i64) (global.get $mut_i64_import))
+
+ (func (export "get const f32 export") (result f32) (global.get $f32_export))
+ (func (export "get const i64 export") (result i64) (global.get $i64_export))
+ (func (export "get var f32 export") (result f32) (global.get $mut_f32_export))
+ (func (export "get var i64 export") (result i64) (global.get $mut_i64_export))
+
+ (func (export "set var f32 import") (param f32) (global.set $mut_f32_import (local.get 0)))
+ (func (export "set var i64 import") (param i64) (global.set $mut_i64_import (local.get 0)))
+
+ (func (export "set var f32 export") (param f32) (global.set $mut_f32_export (local.get 0)))
+ (func (export "set var f64 export") (param i64) (global.set $mut_i64_export (local.get 0)))
+)
diff --git a/deps/v8/third_party/wasm-api/example/hello.c b/deps/v8/third_party/wasm-api/example/hello.c
new file mode 100644
index 0000000000..b1c8c5fee5
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/hello.c
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "wasm.h"
+
+#define own
+
+// A function to be called from Wasm code.
+own wasm_trap_t* hello_callback(
+ const wasm_val_t args[], wasm_val_t results[]
+) {
+ printf("Calling back...\n");
+ printf("> Hello World!\n");
+ return NULL;
+}
+
+
+int main(int argc, const char* argv[]) {
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t* engine = wasm_engine_new();
+ wasm_store_t* store = wasm_store_new(engine);
+
+ // Load binary.
+ printf("Loading binary...\n");
+ FILE* file = fopen("hello.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile.
+ printf("Compiling module...\n");
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ // Create external print functions.
+ printf("Creating callback...\n");
+ own wasm_functype_t* hello_type = wasm_functype_new_0_0();
+ own wasm_func_t* hello_func =
+ wasm_func_new(store, hello_type, hello_callback);
+
+ wasm_functype_delete(hello_type);
+
+ // Instantiate.
+ printf("Instantiating module...\n");
+ const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_func) };
+ own wasm_instance_t* instance = wasm_instance_new(store, module, imports);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ return 1;
+ }
+
+ wasm_func_delete(hello_func);
+
+ // Extract export.
+ printf("Extracting export...\n");
+ own wasm_extern_vec_t exports;
+ wasm_instance_exports(instance, &exports);
+ if (exports.size == 0) {
+ printf("> Error accessing exports!\n");
+ return 1;
+ }
+ const wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]);
+ if (run_func == NULL) {
+ printf("> Error accessing export!\n");
+ return 1;
+ }
+
+ wasm_module_delete(module);
+ wasm_instance_delete(instance);
+
+ // Call.
+ printf("Calling export...\n");
+ if (wasm_func_call(run_func, NULL, NULL)) {
+ printf("> Error calling function!\n");
+ return 1;
+ }
+
+ wasm_extern_vec_delete(&exports);
+
+ // Shut down.
+ printf("Shutting down...\n");
+ wasm_store_delete(store);
+ wasm_engine_delete(engine);
+
+ // All done.
+ printf("Done.\n");
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/hello.cc b/deps/v8/third_party/wasm-api/example/hello.cc
new file mode 100644
index 0000000000..4956be885f
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/hello.cc
@@ -0,0 +1,91 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <cinttypes>
+
+#include "wasm.hh"
+
+
+// A function to be called from Wasm code.
+auto hello_callback(
+ const wasm::Val args[], wasm::Val results[]
+) -> wasm::own<wasm::Trap*> {
+ std::cout << "Calling back..." << std::endl;
+ std::cout << "> Hello world!" << std::endl;
+ return nullptr;
+}
+
+
+void run() {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+ auto store_ = wasm::Store::make(engine.get());
+ auto store = store_.get();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("hello.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return;
+ }
+
+ // Compile.
+ std::cout << "Compiling module..." << std::endl;
+ auto module = wasm::Module::make(store, binary);
+ if (!module) {
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Create external print functions.
+ std::cout << "Creating callback..." << std::endl;
+ auto hello_type = wasm::FuncType::make(
+ wasm::vec<wasm::ValType*>::make(), wasm::vec<wasm::ValType*>::make()
+ );
+ auto hello_func = wasm::Func::make(store, hello_type.get(), hello_callback);
+
+ // Instantiate.
+ std::cout << "Instantiating module..." << std::endl;
+ wasm::Extern* imports[] = {hello_func.get()};
+ auto instance = wasm::Instance::make(store, module.get(), imports);
+ if (!instance) {
+ std::cout << "> Error instantiating module!" << std::endl;
+ return;
+ }
+
+ // Extract export.
+ std::cout << "Extracting export..." << std::endl;
+ auto exports = instance->exports();
+ if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) {
+ std::cout << "> Error accessing export!" << std::endl;
+ return;
+ }
+ auto run_func = exports[0]->func();
+
+ // Call.
+ std::cout << "Calling export..." << std::endl;
+ if (run_func->call()) {
+ std::cout << "> Error calling function!" << std::endl;
+ return;
+ }
+
+ // Shut down.
+ std::cout << "Shutting down..." << std::endl;
+}
+
+
+int main(int argc, const char* argv[]) {
+ run();
+ std::cout << "Done." << std::endl;
+ return 0;
+}
+
diff --git a/deps/v8/third_party/wasm-api/example/hello.wasm b/deps/v8/third_party/wasm-api/example/hello.wasm
new file mode 100644
index 0000000000..2207c03eea
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/hello.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/hello.wat b/deps/v8/third_party/wasm-api/example/hello.wat
new file mode 100644
index 0000000000..1c56c55822
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/hello.wat
@@ -0,0 +1,4 @@
+(module
+ (func $hello (import "" "hello"))
+ (func (export "run") (call $hello))
+)
diff --git a/deps/v8/third_party/wasm-api/example/memory.c b/deps/v8/third_party/wasm-api/example/memory.c
new file mode 100644
index 0000000000..64b0f86b51
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/memory.c
@@ -0,0 +1,217 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "wasm.h"
+
+#define own
+
+
+wasm_memory_t* get_export_memory(const wasm_extern_vec_t* exports, size_t i) {
+ if (exports->size <= i || !wasm_extern_as_memory(exports->data[i])) {
+ printf("> Error accessing memory export %zu!\n", i);
+ exit(1);
+ }
+ return wasm_extern_as_memory(exports->data[i]);
+}
+
+wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) {
+ if (exports->size <= i || !wasm_extern_as_func(exports->data[i])) {
+ printf("> Error accessing function export %zu!\n", i);
+ exit(1);
+ }
+ return wasm_extern_as_func(exports->data[i]);
+}
+
+
+void check(bool success) {
+ if (!success) {
+ printf("> Error, expected success\n");
+ exit(1);
+ }
+}
+
+void check_call(wasm_func_t* func, wasm_val_t args[], int32_t expected) {
+ wasm_val_t results[1];
+ if (wasm_func_call(func, args, results) || results[0].of.i32 != expected) {
+ printf("> Error on result\n");
+ exit(1);
+ }
+}
+
+void check_call0(wasm_func_t* func, int32_t expected) {
+ check_call(func, NULL, expected);
+}
+
+void check_call1(wasm_func_t* func, int32_t arg, int32_t expected) {
+ wasm_val_t args[] = { {.kind = WASM_I32, .of = {.i32 = arg}} };
+ check_call(func, args, expected);
+}
+
+void check_call2(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) {
+ wasm_val_t args[2] = {
+ {.kind = WASM_I32, .of = {.i32 = arg1}},
+ {.kind = WASM_I32, .of = {.i32 = arg2}}
+ };
+ check_call(func, args, expected);
+}
+
+void check_ok(wasm_func_t* func, wasm_val_t args[]) {
+ if (wasm_func_call(func, args, NULL)) {
+ printf("> Error on result, expected empty\n");
+ exit(1);
+ }
+}
+
+void check_ok2(wasm_func_t* func, int32_t arg1, int32_t arg2) {
+ wasm_val_t args[2] = {
+ {.kind = WASM_I32, .of = {.i32 = arg1}},
+ {.kind = WASM_I32, .of = {.i32 = arg2}}
+ };
+ check_ok(func, args);
+}
+
+void check_trap(wasm_func_t* func, wasm_val_t args[]) {
+ wasm_val_t results[1];
+ own wasm_trap_t* trap = wasm_func_call(func, args, results);
+ if (! trap) {
+ printf("> Error on result, expected trap\n");
+ exit(1);
+ }
+ wasm_trap_delete(trap);
+}
+
+void check_trap1(wasm_func_t* func, int32_t arg) {
+ wasm_val_t args[1] = { {.kind = WASM_I32, .of = {.i32 = arg}} };
+ check_trap(func, args);
+}
+
+void check_trap2(wasm_func_t* func, int32_t arg1, int32_t arg2) {
+ wasm_val_t args[2] = {
+ {.kind = WASM_I32, .of = {.i32 = arg1}},
+ {.kind = WASM_I32, .of = {.i32 = arg2}}
+ };
+ check_trap(func, args);
+}
+
+
+int main(int argc, const char* argv[]) {
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t* engine = wasm_engine_new();
+ wasm_store_t* store = wasm_store_new(engine);
+
+ // Load binary.
+ printf("Loading binary...\n");
+ FILE* file = fopen("memory.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile.
+ printf("Compiling module...\n");
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ // Instantiate.
+ printf("Instantiating module...\n");
+ own wasm_instance_t* instance = wasm_instance_new(store, module, NULL);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ return 1;
+ }
+
+ // Extract export.
+ printf("Extracting exports...\n");
+ own wasm_extern_vec_t exports;
+ wasm_instance_exports(instance, &exports);
+ size_t i = 0;
+ wasm_memory_t* memory = get_export_memory(&exports, i++);
+ wasm_func_t* size_func = get_export_func(&exports, i++);
+ wasm_func_t* load_func = get_export_func(&exports, i++);
+ wasm_func_t* store_func = get_export_func(&exports, i++);
+
+ wasm_module_delete(module);
+
+ // Check initial memory.
+ printf("Checking memory...\n");
+ check(wasm_memory_size(memory) == 2);
+ check(wasm_memory_data_size(memory) == 0x20000);
+ check(wasm_memory_data(memory)[0] == 0);
+ check(wasm_memory_data(memory)[0x1000] == 1);
+ check(wasm_memory_data(memory)[0x1003] == 4);
+
+ check_call0(size_func, 2);
+ check_call1(load_func, 0, 0);
+ check_call1(load_func, 0x1000, 1);
+ check_call1(load_func, 0x1003, 4);
+ check_call1(load_func, 0x1ffff, 0);
+ check_trap1(load_func, 0x20000);
+
+ // Mutate memory.
+ printf("Mutating memory...\n");
+ wasm_memory_data(memory)[0x1003] = 5;
+ check_ok2(store_func, 0x1002, 6);
+ check_trap2(store_func, 0x20000, 0);
+
+ check(wasm_memory_data(memory)[0x1002] == 6);
+ check(wasm_memory_data(memory)[0x1003] == 5);
+ check_call1(load_func, 0x1002, 6);
+ check_call1(load_func, 0x1003, 5);
+
+ // Grow memory.
+ printf("Growing memory...\n");
+ check(wasm_memory_grow(memory, 1));
+ check(wasm_memory_size(memory) == 3);
+ check(wasm_memory_data_size(memory) == 0x30000);
+
+ check_call1(load_func, 0x20000, 0);
+ check_ok2(store_func, 0x20000, 0);
+ check_trap1(load_func, 0x30000);
+ check_trap2(store_func, 0x30000, 0);
+
+ check(! wasm_memory_grow(memory, 1));
+ check(wasm_memory_grow(memory, 0));
+
+ wasm_extern_vec_delete(&exports);
+ wasm_instance_delete(instance);
+
+ // Create stand-alone memory.
+ // TODO(wasm+): Once Wasm allows multiple memories, turn this into import.
+ printf("Creating stand-alone memory...\n");
+ wasm_limits_t limits = {5, 5};
+ own wasm_memorytype_t* memorytype = wasm_memorytype_new(&limits);
+ own wasm_memory_t* memory2 = wasm_memory_new(store, memorytype);
+ check(wasm_memory_size(memory2) == 5);
+ check(! wasm_memory_grow(memory2, 1));
+ check(wasm_memory_grow(memory2, 0));
+
+ wasm_memorytype_delete(memorytype);
+ wasm_memory_delete(memory2);
+
+ // Shut down.
+ printf("Shutting down...\n");
+ wasm_store_delete(store);
+ wasm_engine_delete(engine);
+
+ // All done.
+ printf("Done.\n");
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/memory.cc b/deps/v8/third_party/wasm-api/example/memory.cc
new file mode 100644
index 0000000000..fb50565c85
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/memory.cc
@@ -0,0 +1,169 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <cinttypes>
+
+#include "wasm.hh"
+
+
+auto get_export_memory(wasm::vec<wasm::Extern*>& exports, size_t i) -> wasm::Memory* {
+ if (exports.size() <= i || !exports[i]->memory()) {
+ std::cout << "> Error accessing memory export " << i << "!" << std::endl;
+ exit(1);
+ }
+ return exports[i]->memory();
+}
+
+auto get_export_func(const wasm::vec<wasm::Extern*>& exports, size_t i) -> const wasm::Func* {
+ if (exports.size() <= i || !exports[i]->func()) {
+ std::cout << "> Error accessing function export " << i << "!" << std::endl;
+ exit(1);
+ }
+ return exports[i]->func();
+}
+
+template<class T, class U>
+void check(T actual, U expected) {
+ if (actual != expected) {
+ std::cout << "> Error on result, expected " << expected << ", got " << actual << std::endl;
+ exit(1);
+ }
+}
+
+template<class... Args>
+void check_ok(const wasm::Func* func, Args... xs) {
+ wasm::Val args[] = {wasm::Val::i32(xs)...};
+ if (func->call(args)) {
+ std::cout << "> Error on result, expected return" << std::endl;
+ exit(1);
+ }
+}
+
+template<class... Args>
+void check_trap(const wasm::Func* func, Args... xs) {
+ wasm::Val args[] = {wasm::Val::i32(xs)...};
+ if (! func->call(args)) {
+ std::cout << "> Error on result, expected trap" << std::endl;
+ exit(1);
+ }
+}
+
+template<class... Args>
+auto call(const wasm::Func* func, Args... xs) -> int32_t {
+ wasm::Val args[] = {wasm::Val::i32(xs)...};
+ wasm::Val results[1];
+ if (func->call(args, results)) {
+ std::cout << "> Error on result, expected return" << std::endl;
+ exit(1);
+ }
+ return results[0].i32();
+}
+
+
+void run() {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+ auto store_ = wasm::Store::make(engine.get());
+ auto store = store_.get();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("memory.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return;
+ }
+
+ // Compile.
+ std::cout << "Compiling module..." << std::endl;
+ auto module = wasm::Module::make(store, binary);
+ if (!module) {
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Instantiate.
+ std::cout << "Instantiating module..." << std::endl;
+ auto instance = wasm::Instance::make(store, module.get(), nullptr);
+ if (!instance) {
+ std::cout << "> Error instantiating module!" << std::endl;
+ return;
+ }
+
+ // Extract export.
+ std::cout << "Extracting exports..." << std::endl;
+ auto exports = instance->exports();
+ size_t i = 0;
+ auto memory = get_export_memory(exports, i++);
+ auto size_func = get_export_func(exports, i++);
+ auto load_func = get_export_func(exports, i++);
+ auto store_func = get_export_func(exports, i++);
+
+ // Check initial memory.
+ std::cout << "Checking memory..." << std::endl;
+ check(memory->size(), 2u);
+ check(memory->data_size(), 0x20000u);
+ check(memory->data()[0], 0);
+ check(memory->data()[0x1000], 1);
+ check(memory->data()[0x1003], 4);
+
+ check(call(size_func), 2);
+ check(call(load_func, 0), 0);
+ check(call(load_func, 0x1000), 1);
+ check(call(load_func, 0x1003), 4);
+ check(call(load_func, 0x1ffff), 0);
+ check_trap(load_func, 0x20000);
+
+ // Mutate memory.
+ std::cout << "Mutating memory..." << std::endl;
+ memory->data()[0x1003] = 5;
+ check_ok(store_func, 0x1002, 6);
+ check_trap(store_func, 0x20000, 0);
+
+ check(memory->data()[0x1002], 6);
+ check(memory->data()[0x1003], 5);
+ check(call(load_func, 0x1002), 6);
+ check(call(load_func, 0x1003), 5);
+
+ // Grow memory.
+ std::cout << "Growing memory..." << std::endl;
+ check(memory->grow(1), true);
+ check(memory->size(), 3u);
+ check(memory->data_size(), 0x30000u);
+
+ check(call(load_func, 0x20000), 0);
+ check_ok(store_func, 0x20000, 0);
+ check_trap(load_func, 0x30000);
+ check_trap(store_func, 0x30000, 0);
+
+ check(memory->grow(1), false);
+ check(memory->grow(0), true);
+
+ // Create stand-alone memory.
+ // TODO(wasm+): Once Wasm allows multiple memories, turn this into import.
+ std::cout << "Creating stand-alone memory..." << std::endl;
+ auto memorytype = wasm::MemoryType::make(wasm::Limits(5, 5));
+ auto memory2 = wasm::Memory::make(store, memorytype.get());
+ check(memory2->size(), 5u);
+ check(memory2->grow(1), false);
+ check(memory2->grow(0), true);
+
+ // Shut down.
+ std::cout << "Shutting down..." << std::endl;
+}
+
+
+int main(int argc, const char* argv[]) {
+ run();
+ std::cout << "Done." << std::endl;
+ return 0;
+}
+
diff --git a/deps/v8/third_party/wasm-api/example/memory.wasm b/deps/v8/third_party/wasm-api/example/memory.wasm
new file mode 100644
index 0000000000..6f6518b187
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/memory.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/memory.wat b/deps/v8/third_party/wasm-api/example/memory.wat
new file mode 100644
index 0000000000..4cf43e2c7d
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/memory.wat
@@ -0,0 +1,11 @@
+(module
+ (memory (export "memory") 2 3)
+
+ (func (export "size") (result i32) (memory.size))
+ (func (export "load") (param i32) (result i32) (i32.load8_s (local.get 0)))
+ (func (export "store") (param i32 i32)
+ (i32.store8 (local.get 0) (local.get 1))
+ )
+
+ (data (i32.const 0x1000) "\01\02\03\04")
+)
diff --git a/deps/v8/third_party/wasm-api/example/reflect.c b/deps/v8/third_party/wasm-api/example/reflect.c
new file mode 100644
index 0000000000..a210a85c15
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/reflect.c
@@ -0,0 +1,164 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "wasm.h"
+
+#define own
+
+void print_mutability(wasm_mutability_t mut) {
+ switch (mut) {
+ case WASM_VAR: printf("var"); break;
+ case WASM_CONST: printf("const"); break;
+ }
+}
+
+void print_limits(const wasm_limits_t* limits) {
+ printf("%ud", limits->min);
+ if (limits->max < wasm_limits_max_default) printf(" %ud", limits->max);
+}
+
+void print_valtype(const wasm_valtype_t* type) {
+ switch (wasm_valtype_kind(type)) {
+ case WASM_I32: printf("i32"); break;
+ case WASM_I64: printf("i64"); break;
+ case WASM_F32: printf("f32"); break;
+ case WASM_F64: printf("f64"); break;
+ case WASM_ANYREF: printf("anyref"); break;
+ case WASM_FUNCREF: printf("funcref"); break;
+ }
+}
+
+void print_valtypes(const wasm_valtype_vec_t* types) {
+ bool first = true;
+ for (size_t i = 0; i < types->size; ++i) {
+ if (first) {
+ first = false;
+ } else {
+ printf(" ");
+ }
+ print_valtype(types->data[i]);
+ }
+}
+
+void print_externtype(const wasm_externtype_t* type) {
+ switch (wasm_externtype_kind(type)) {
+ case WASM_EXTERN_FUNC: {
+ const wasm_functype_t* functype = wasm_externtype_as_functype_const(type);
+ printf("func ");
+ print_valtypes(wasm_functype_params(functype));
+ printf(" -> ");
+ print_valtypes(wasm_functype_results(functype));
+ } break;
+ case WASM_EXTERN_GLOBAL: {
+ const wasm_globaltype_t* globaltype = wasm_externtype_as_globaltype_const(type);
+ printf("global ");
+ print_mutability(wasm_globaltype_mutability(globaltype));
+ printf(" ");
+ print_valtype(wasm_globaltype_content(globaltype));
+ } break;
+ case WASM_EXTERN_TABLE: {
+ const wasm_tabletype_t* tabletype = wasm_externtype_as_tabletype_const(type);
+ printf("table ");
+ print_limits(wasm_tabletype_limits(tabletype));
+ printf(" ");
+ print_valtype(wasm_tabletype_element(tabletype));
+ } break;
+ case WASM_EXTERN_MEMORY: {
+ const wasm_memorytype_t* memorytype = wasm_externtype_as_memorytype_const(type);
+ printf("memory ");
+ print_limits(wasm_memorytype_limits(memorytype));
+ } break;
+ }
+}
+
+void print_name(const wasm_name_t* name) {
+ printf("\"%.*s\"", (int)name->size, name->data);
+}
+
+
+int main(int argc, const char* argv[]) {
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t* engine = wasm_engine_new();
+ wasm_store_t* store = wasm_store_new(engine);
+
+ // Load binary.
+ printf("Loading binary...\n");
+ FILE* file = fopen("reflect.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile.
+ printf("Compiling module...\n");
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ // Instantiate.
+ printf("Instantiating module...\n");
+ own wasm_instance_t* instance = wasm_instance_new(store, module, NULL);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ return 1;
+ }
+
+ // Extract export.
+ printf("Extracting export...\n");
+ own wasm_exporttype_vec_t export_types;
+ own wasm_extern_vec_t exports;
+ wasm_module_exports(module, &export_types);
+ wasm_instance_exports(instance, &exports);
+ assert(exports.size == export_types.size);
+
+ for (size_t i = 0; i < exports.size; ++i) {
+ assert(wasm_extern_kind(exports.data[i]) == wasm_externtype_kind(wasm_exporttype_type(export_types.data[i])));
+ printf("> export %zu ", i);
+ print_name(wasm_exporttype_name(export_types.data[i]));
+ printf("\n");
+ printf(">> initial: ");
+ print_externtype(wasm_exporttype_type(export_types.data[i]));
+ printf("\n");
+ printf(">> current: ");
+ own wasm_externtype_t* current = wasm_extern_type(exports.data[i]);
+ print_externtype(current);
+ wasm_externtype_delete(current);
+ printf("\n");
+ if (wasm_extern_kind(exports.data[i]) == WASM_EXTERN_FUNC) {
+ wasm_func_t* func = wasm_extern_as_func(exports.data[i]);
+ printf(">> in-arity: %zu", wasm_func_param_arity(func));
+ printf(", out-arity: %zu\n", wasm_func_result_arity(func));
+ }
+ }
+
+ wasm_module_delete(module);
+ wasm_instance_delete(instance);
+ wasm_extern_vec_delete(&exports);
+ wasm_exporttype_vec_delete(&export_types);
+
+ // Shut down.
+ printf("Shutting down...\n");
+ wasm_store_delete(store);
+ wasm_engine_delete(engine);
+
+ // All done.
+ printf("Done.\n");
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/reflect.cc b/deps/v8/third_party/wasm-api/example/reflect.cc
new file mode 100644
index 0000000000..c04b9e4d4e
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/reflect.cc
@@ -0,0 +1,138 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <cinttypes>
+
+#include "wasm.hh"
+
+
+auto operator<<(std::ostream& out, wasm::Mutability mut) -> std::ostream& {
+ switch (mut) {
+ case wasm::VAR: return out << "var";
+ case wasm::CONST: return out << "const";
+ }
+ return out;
+}
+
+auto operator<<(std::ostream& out, wasm::Limits limits) -> std::ostream& {
+ out << limits.min;
+ if (limits.max < wasm::Limits(0).max) out << " " << limits.max;
+ return out;
+}
+
+auto operator<<(std::ostream& out, const wasm::ValType& type) -> std::ostream& {
+ switch (type.kind()) {
+ case wasm::I32: return out << "i32";
+ case wasm::I64: return out << "i64";
+ case wasm::F32: return out << "f32";
+ case wasm::F64: return out << "f64";
+ case wasm::ANYREF: return out << "anyref";
+ case wasm::FUNCREF: return out << "funcref";
+ }
+ return out;
+}
+
+auto operator<<(std::ostream& out, const wasm::vec<wasm::ValType*>& types) -> std::ostream& {
+ bool first = true;
+ for (size_t i = 0; i < types.size(); ++i) {
+ if (first) {
+ first = false;
+ } else {
+ out << " ";
+ }
+ out << *types[i].get();
+ }
+ return out;
+}
+
+auto operator<<(std::ostream& out, const wasm::ExternType& type) -> std::ostream& {
+ switch (type.kind()) {
+ case wasm::EXTERN_FUNC: {
+ out << "func " << type.func()->params() << " -> " << type.func()->results();
+ } break;
+ case wasm::EXTERN_GLOBAL: {
+ out << "global " << type.global()->mutability() << " " << *type.global()->content();
+ } break;
+ case wasm::EXTERN_TABLE: {
+ out << "table " << type.table()->limits() << " " << *type.table()->element();
+ } break;
+ case wasm::EXTERN_MEMORY: {
+ out << "memory " << type.memory()->limits();
+ } break;
+ }
+ return out;
+}
+
+auto operator<<(std::ostream& out, const wasm::Name& name) -> std::ostream& {
+ out << "\"" << std::string(name.get(), name.size()) << "\"";
+ return out;
+}
+
+
+void run() {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+ auto store_ = wasm::Store::make(engine.get());
+ auto store = store_.get();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("reflect.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return;
+ }
+
+ // Compile.
+ std::cout << "Compiling module..." << std::endl;
+ auto module = wasm::Module::make(store, binary);
+ if (!module) {
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Instantiate.
+ std::cout << "Instantiating module..." << std::endl;
+ auto instance = wasm::Instance::make(store, module.get(), nullptr);
+ if (!instance) {
+ std::cout << "> Error instantiating module!" << std::endl;
+ return;
+ }
+
+ // Extract exports.
+ std::cout << "Extracting export..." << std::endl;
+ auto export_types = module->exports();
+ auto exports = instance->exports();
+ assert(exports.size() == export_types.size());
+
+ for (size_t i = 0; i < exports.size(); ++i) {
+ assert(exports[i]->kind() == export_types[i]->type()->kind());
+ std::cout << "> export " << i << " " << export_types[i]->name() << std::endl;
+ std::cout << ">> initial: " << *export_types[i]->type() << std::endl;
+ std::cout << ">> current: " << *exports[i]->type() << std::endl;
+ if (exports[i]->kind() == wasm::EXTERN_FUNC) {
+ auto func = exports[i]->func();
+ std::cout << ">> in-arity: " << func->param_arity();
+ std::cout << ", out-arity: " << func->result_arity() << std::endl;
+ }
+ }
+
+ // Shut down.
+ std::cout << "Shutting down..." << std::endl;
+}
+
+
+int main(int argc, const char* argv[]) {
+ run();
+ std::cout << "Done." << std::endl;
+ return 0;
+}
+
diff --git a/deps/v8/third_party/wasm-api/example/reflect.wasm b/deps/v8/third_party/wasm-api/example/reflect.wasm
new file mode 100644
index 0000000000..15a68fe8f7
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/reflect.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/reflect.wat b/deps/v8/third_party/wasm-api/example/reflect.wat
new file mode 100644
index 0000000000..261dfd3c33
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/reflect.wat
@@ -0,0 +1,6 @@
+(module
+ (func (export "func") (param i32 f64 f32) (result i32) (unreachable))
+ (global (export "global") f64 (f64.const 0))
+ (table (export "table") 0 50 anyfunc)
+ (memory (export "memory") 1)
+)
diff --git a/deps/v8/third_party/wasm-api/example/serialize.c b/deps/v8/third_party/wasm-api/example/serialize.c
new file mode 100644
index 0000000000..8c7efc2ee9
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/serialize.c
@@ -0,0 +1,122 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "wasm.h"
+
+#define own
+
+// A function to be called from Wasm code.
+own wasm_trap_t* hello_callback(const wasm_val_t args[], wasm_val_t results[]) {
+ printf("Calling back...\n");
+ printf("> Hello World!\n");
+ return NULL;
+}
+
+
+int main(int argc, const char* argv[]) {
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t* engine = wasm_engine_new();
+ wasm_store_t* store = wasm_store_new(engine);
+
+ // Load binary.
+ printf("Loading binary...\n");
+ FILE* file = fopen("serialize.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile.
+ printf("Compiling module...\n");
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ // Serialize module.
+ printf("Serializing module...\n");
+ own wasm_byte_vec_t serialized;
+ wasm_module_serialize(module, &serialized);
+
+ wasm_module_delete(module);
+
+ // Deserialize module.
+ printf("Deserializing module...\n");
+ own wasm_module_t* deserialized = wasm_module_deserialize(store, &serialized);
+ if (!deserialized) {
+ printf("> Error deserializing module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&serialized);
+
+ // Create external print functions.
+ printf("Creating callback...\n");
+ own wasm_functype_t* hello_type = wasm_functype_new_0_0();
+ own wasm_func_t* hello_func =
+ wasm_func_new(store, hello_type, hello_callback);
+
+ wasm_functype_delete(hello_type);
+
+ // Instantiate.
+ printf("Instantiating deserialized module...\n");
+ const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_func) };
+ own wasm_instance_t* instance = wasm_instance_new(store, deserialized, imports);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ return 1;
+ }
+
+ wasm_func_delete(hello_func);
+
+ // Extract export.
+ printf("Extracting export...\n");
+ own wasm_extern_vec_t exports;
+ wasm_instance_exports(instance, &exports);
+ if (exports.size == 0) {
+ printf("> Error accessing exports!\n");
+ return 1;
+ }
+ const wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]);
+ if (run_func == NULL) {
+ printf("> Error accessing export!\n");
+ return 1;
+ }
+
+ wasm_module_delete(deserialized);
+ wasm_instance_delete(instance);
+
+ // Call.
+ printf("Calling export...\n");
+ if (wasm_func_call(run_func, NULL, NULL)) {
+ printf("> Error calling function!\n");
+ return 1;
+ }
+
+ wasm_extern_vec_delete(&exports);
+
+ // Shut down.
+ printf("Shutting down...\n");
+ wasm_store_delete(store);
+ wasm_engine_delete(engine);
+
+ // All done.
+ printf("Done.\n");
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/serialize.cc b/deps/v8/third_party/wasm-api/example/serialize.cc
new file mode 100644
index 0000000000..895ef396e0
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/serialize.cc
@@ -0,0 +1,103 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <cinttypes>
+
+#include "wasm.hh"
+
+
+// A function to be called from Wasm code.
+auto hello_callback(
+ const wasm::Val args[], wasm::Val results[]
+) -> wasm::own<wasm::Trap*> {
+ std::cout << "Calling back..." << std::endl;
+ std::cout << "> Hello world!" << std::endl;
+ return nullptr;
+}
+
+
+void run() {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+ auto store_ = wasm::Store::make(engine.get());
+ auto store = store_.get();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("serialize.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return;
+ }
+
+ // Compile.
+ std::cout << "Compiling module..." << std::endl;
+ auto module = wasm::Module::make(store, binary);
+ if (!module) {
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Serialize module.
+ std::cout << "Serializing module..." << std::endl;
+ auto serialized = module->serialize();
+
+ // Deserialize module.
+ std::cout << "Deserializing module..." << std::endl;
+ auto deserialized = wasm::Module::deserialize(store, serialized);
+ if (!deserialized) {
+ std::cout << "> Error deserializing module!" << std::endl;
+ return;
+ }
+
+ // Create external print functions.
+ std::cout << "Creating callback..." << std::endl;
+ auto hello_type = wasm::FuncType::make(
+ wasm::vec<wasm::ValType*>::make(), wasm::vec<wasm::ValType*>::make()
+ );
+ auto hello_func = wasm::Func::make(store, hello_type.get(), hello_callback);
+
+ // Instantiate.
+ std::cout << "Instantiating deserialized module..." << std::endl;
+ wasm::Extern* imports[] = {hello_func.get()};
+ auto instance = wasm::Instance::make(store, deserialized.get(), imports);
+ if (!instance) {
+ std::cout << "> Error instantiating module!" << std::endl;
+ return;
+ }
+
+ // Extract export.
+ std::cout << "Extracting export..." << std::endl;
+ auto exports = instance->exports();
+ if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) {
+ std::cout << "> Error accessing export!" << std::endl;
+ return;
+ }
+ auto run_func = exports[0]->func();
+
+ // Call.
+ std::cout << "Calling export..." << std::endl;
+ if (! run_func->call()) {
+ std::cout << "> Error calling function!" << std::endl;
+ return;
+ }
+
+ // Shut down.
+ std::cout << "Shutting down..." << std::endl;
+}
+
+
+int main(int argc, const char* argv[]) {
+ run();
+ std::cout << "Done." << std::endl;
+ return 0;
+}
+
diff --git a/deps/v8/third_party/wasm-api/example/serialize.wasm b/deps/v8/third_party/wasm-api/example/serialize.wasm
new file mode 100644
index 0000000000..2207c03eea
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/serialize.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/serialize.wat b/deps/v8/third_party/wasm-api/example/serialize.wat
new file mode 100644
index 0000000000..1c56c55822
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/serialize.wat
@@ -0,0 +1,4 @@
+(module
+ (func $hello (import "" "hello"))
+ (func (export "run") (call $hello))
+)
diff --git a/deps/v8/third_party/wasm-api/example/table.c b/deps/v8/third_party/wasm-api/example/table.c
new file mode 100644
index 0000000000..8fec71f23f
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/table.c
@@ -0,0 +1,208 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "wasm.h"
+
+#define own
+
+// A function to be called from Wasm code.
+own wasm_trap_t* neg_callback(
+ const wasm_val_t args[], wasm_val_t results[]
+) {
+ printf("Calling back...\n");
+ results[0].kind = WASM_I32;
+ results[0].of.i32 = -args[0].of.i32;
+ return NULL;
+}
+
+
+wasm_table_t* get_export_table(const wasm_extern_vec_t* exports, size_t i) {
+ if (exports->size <= i || !wasm_extern_as_table(exports->data[i])) {
+ printf("> Error accessing table export %zu!\n", i);
+ exit(1);
+ }
+ return wasm_extern_as_table(exports->data[i]);
+}
+
+wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) {
+ if (exports->size <= i || !wasm_extern_as_func(exports->data[i])) {
+ printf("> Error accessing function export %zu!\n", i);
+ exit(1);
+ }
+ return wasm_extern_as_func(exports->data[i]);
+}
+
+
+void check(bool success) {
+ if (!success) {
+ printf("> Error, expected success\n");
+ exit(1);
+ }
+}
+
+void check_table(wasm_table_t* table, int32_t i, bool expect_set) {
+ own wasm_ref_t* ref = wasm_table_get(table, i);
+ check((ref != NULL) == expect_set);
+ if (ref) wasm_ref_delete(ref);
+}
+
+void check_call(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) {
+ wasm_val_t args[2] = {
+ {.kind = WASM_I32, .of = {.i32 = arg1}},
+ {.kind = WASM_I32, .of = {.i32 = arg2}}
+ };
+ wasm_val_t results[1];
+ if (wasm_func_call(func, args, results) || results[0].of.i32 != expected) {
+ printf("> Error on result\n");
+ exit(1);
+ }
+}
+
+void check_trap(wasm_func_t* func, int32_t arg1, int32_t arg2) {
+ wasm_val_t args[2] = {
+ {.kind = WASM_I32, .of = {.i32 = arg1}},
+ {.kind = WASM_I32, .of = {.i32 = arg2}}
+ };
+ own wasm_trap_t* trap = wasm_func_call(func, args, NULL);
+ if (! trap) {
+ printf("> Error on result, expected trap\n");
+ exit(1);
+ }
+ wasm_trap_delete(trap);
+}
+
+
+int main(int argc, const char* argv[]) {
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t* engine = wasm_engine_new();
+ wasm_store_t* store = wasm_store_new(engine);
+
+ // Load binary.
+ printf("Loading binary...\n");
+ FILE* file = fopen("table.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile.
+ printf("Compiling module...\n");
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ // Instantiate.
+ printf("Instantiating module...\n");
+ own wasm_instance_t* instance = wasm_instance_new(store, module, NULL);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ return 1;
+ }
+
+ // Extract export.
+ printf("Extracting exports...\n");
+ own wasm_extern_vec_t exports;
+ wasm_instance_exports(instance, &exports);
+ size_t i = 0;
+ wasm_table_t* table = get_export_table(&exports, i++);
+ wasm_func_t* call_indirect = get_export_func(&exports, i++);
+ wasm_func_t* f = get_export_func(&exports, i++);
+ wasm_func_t* g = get_export_func(&exports, i++);
+
+ wasm_module_delete(module);
+
+ // Create external function.
+ printf("Creating callback...\n");
+ own wasm_functype_t* neg_type = wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32());
+ own wasm_func_t* h = wasm_func_new(store, neg_type, neg_callback);
+
+ wasm_functype_delete(neg_type);
+
+ // Check initial table.
+ printf("Checking table...\n");
+ check(wasm_table_size(table) == 2);
+ check_table(table, 0, false);
+ check_table(table, 1, true);
+ check_trap(call_indirect, 0, 0);
+ check_call(call_indirect, 7, 1, 7);
+ check_trap(call_indirect, 0, 2);
+
+ // Mutate table.
+ printf("Mutating table...\n");
+ check(wasm_table_set(table, 0, wasm_func_as_ref(g)));
+ check(wasm_table_set(table, 1, NULL));
+ check(! wasm_table_set(table, 2, wasm_func_as_ref(f)));
+ check_table(table, 0, true);
+ check_table(table, 1, false);
+ check_call(call_indirect, 7, 0, 666);
+ check_trap(call_indirect, 0, 1);
+ check_trap(call_indirect, 0, 2);
+
+ // Grow table.
+ printf("Growing table...\n");
+ check(wasm_table_grow(table, 3, NULL));
+ check(wasm_table_size(table) == 5);
+ check(wasm_table_set(table, 2, wasm_func_as_ref(f)));
+ check(wasm_table_set(table, 3, wasm_func_as_ref(h)));
+ check(! wasm_table_set(table, 5, NULL));
+ check_table(table, 2, true);
+ check_table(table, 3, true);
+ check_table(table, 4, false);
+ check_call(call_indirect, 5, 2, 5);
+ check_call(call_indirect, 6, 3, -6);
+ check_trap(call_indirect, 0, 4);
+ check_trap(call_indirect, 0, 5);
+
+ check(wasm_table_grow(table, 2, wasm_func_as_ref(f)));
+ check(wasm_table_size(table) == 7);
+ check_table(table, 5, true);
+ check_table(table, 6, true);
+
+ check(! wasm_table_grow(table, 5, NULL));
+ check(wasm_table_grow(table, 3, NULL));
+ check(wasm_table_grow(table, 0, NULL));
+
+ wasm_func_delete(h);
+ wasm_extern_vec_delete(&exports);
+ wasm_instance_delete(instance);
+
+ // Create stand-alone table.
+ // TODO(wasm+): Once Wasm allows multiple tables, turn this into import.
+ printf("Creating stand-alone table...\n");
+ wasm_limits_t limits = {5, 5};
+ own wasm_tabletype_t* tabletype =
+ wasm_tabletype_new(wasm_valtype_new(WASM_FUNCREF), &limits);
+ own wasm_table_t* table2 = wasm_table_new(store, tabletype, NULL);
+ check(wasm_table_size(table2) == 5);
+ check(! wasm_table_grow(table2, 1, NULL));
+ check(wasm_table_grow(table2, 0, NULL));
+
+ wasm_tabletype_delete(tabletype);
+ wasm_table_delete(table2);
+
+ // Shut down.
+ printf("Shutting down...\n");
+ wasm_store_delete(store);
+ wasm_engine_delete(engine);
+
+ // All done.
+ printf("Done.\n");
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/table.cc b/deps/v8/third_party/wasm-api/example/table.cc
new file mode 100644
index 0000000000..cb669cdb16
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/table.cc
@@ -0,0 +1,189 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <cinttypes>
+
+#include "wasm.hh"
+
+
+// A function to be called from Wasm code.
+auto neg_callback(
+ const wasm::Val args[], wasm::Val results[]
+) -> wasm::own<wasm::Trap*> {
+ std::cout << "Calling back..." << std::endl;
+ results[0] = wasm::Val(-args[0].i32());
+ return nullptr;
+}
+
+
+auto get_export_table(wasm::vec<wasm::Extern*>& exports, size_t i) -> wasm::Table* {
+ if (exports.size() <= i || !exports[i]->table()) {
+ std::cout << "> Error accessing table export " << i << "!" << std::endl;
+ exit(1);
+ }
+ return exports[i]->table();
+}
+
+auto get_export_func(const wasm::vec<wasm::Extern*>& exports, size_t i) -> const wasm::Func* {
+ if (exports.size() <= i || !exports[i]->func()) {
+ std::cout << "> Error accessing function export " << i << "!" << std::endl;
+ exit(1);
+ }
+ return exports[i]->func();
+}
+
+template<class T, class U>
+void check(T actual, U expected) {
+ if (actual != expected) {
+ std::cout << "> Error on result, expected " << expected << ", got " << actual << std::endl;
+ exit(1);
+ }
+}
+
+void check(bool success) {
+ if (! success) {
+ std::cout << "> Error, expected success" << std::endl;
+ exit(1);
+ }
+}
+
+auto call(
+ const wasm::Func* func, wasm::Val&& arg1, wasm::Val&& arg2
+) -> wasm::Val {
+ wasm::Val args[2] = {std::move(arg1), std::move(arg2)};
+ wasm::Val results[1];
+ if (func->call(args, results)) {
+ std::cout << "> Error on result, expected return" << std::endl;
+ exit(1);
+ }
+ return results[0].copy();
+}
+
+void check_trap(const wasm::Func* func, wasm::Val&& arg1, wasm::Val&& arg2) {
+ wasm::Val args[2] = {std::move(arg1), std::move(arg2)};
+ wasm::Val results[1];
+ if (! func->call(args, results)) {
+ std::cout << "> Error on result, expected trap" << std::endl;
+ exit(1);
+ }
+}
+
+void run() {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+ auto store_ = wasm::Store::make(engine.get());
+ auto store = store_.get();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("table.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return;
+ }
+
+ // Compile.
+ std::cout << "Compiling module..." << std::endl;
+ auto module = wasm::Module::make(store, binary);
+ if (!module) {
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Instantiate.
+ std::cout << "Instantiating module..." << std::endl;
+ auto instance = wasm::Instance::make(store, module.get(), nullptr);
+ if (!instance) {
+ std::cout << "> Error instantiating module!" << std::endl;
+ return;
+ }
+
+ // Extract export.
+ std::cout << "Extracting exports..." << std::endl;
+ auto exports = instance->exports();
+ size_t i = 0;
+ auto table = get_export_table(exports, i++);
+ auto call_indirect = get_export_func(exports, i++);
+ auto f = get_export_func(exports, i++);
+ auto g = get_export_func(exports, i++);
+
+ // Create external function.
+ std::cout << "Creating callback..." << std::endl;
+ auto neg_type = wasm::FuncType::make(
+ wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)),
+ wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32))
+ );
+ auto h = wasm::Func::make(store, neg_type.get(), neg_callback);
+
+ // Check initial table.
+ std::cout << "Checking table..." << std::endl;
+ check(table->size(), 2u);
+ check(table->get(0) == nullptr);
+ check(table->get(1) != nullptr);
+ check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(0));
+ check(call(call_indirect, wasm::Val::i32(7), wasm::Val::i32(1)).i32(), 7);
+ check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(2));
+
+ // Mutate table.
+ std::cout << "Mutating table..." << std::endl;
+ check(table->set(0, g));
+ check(table->set(1, nullptr));
+ check(! table->set(2, f));
+ check(table->get(0) != nullptr);
+ check(table->get(1) == nullptr);
+ check(call(call_indirect, wasm::Val::i32(7), wasm::Val::i32(0)).i32(), 666);
+ check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(1));
+ check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(2));
+
+ // Grow table.
+ std::cout << "Growing table..." << std::endl;
+ check(table->grow(3));
+ check(table->size(), 5u);
+ check(table->set(2, f));
+ check(table->set(3, h.get()));
+ check(! table->set(5, nullptr));
+ check(table->get(2) != nullptr);
+ check(table->get(3) != nullptr);
+ check(table->get(4) == nullptr);
+ check(call(call_indirect, wasm::Val::i32(5), wasm::Val::i32(2)).i32(), 5);
+ check(call(call_indirect, wasm::Val::i32(6), wasm::Val::i32(3)).i32(), -6);
+ check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(4));
+ check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(5));
+
+ check(table->grow(2, f));
+ check(table->size(), 7u);
+ check(table->get(5) != nullptr);
+ check(table->get(6) != nullptr);
+
+ check(! table->grow(5));
+ check(table->grow(3));
+ check(table->grow(0));
+
+ // Create stand-alone table.
+ // TODO(wasm+): Once Wasm allows multiple tables, turn this into import.
+ std::cout << "Creating stand-alone table..." << std::endl;
+ auto tabletype = wasm::TableType::make(
+ wasm::ValType::make(wasm::FUNCREF), wasm::Limits(5, 5));
+ auto table2 = wasm::Table::make(store, tabletype.get());
+ check(table2->size() == 5);
+ check(! table2->grow(1));
+ check(table2->grow(0));
+
+ // Shut down.
+ std::cout << "Shutting down..." << std::endl;
+}
+
+
+int main(int argc, const char* argv[]) {
+ run();
+ std::cout << "Done." << std::endl;
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/table.wasm b/deps/v8/third_party/wasm-api/example/table.wasm
new file mode 100644
index 0000000000..cdc0d8c35d
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/table.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/table.wat b/deps/v8/third_party/wasm-api/example/table.wat
new file mode 100644
index 0000000000..d3e3a945aa
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/table.wat
@@ -0,0 +1,12 @@
+(module
+ (table (export "table") 2 10 funcref)
+
+ (func (export "call_indirect") (param i32 i32) (result i32)
+ (call_indirect (param i32) (result i32) (local.get 0) (local.get 1))
+ )
+
+ (func $f (export "f") (param i32) (result i32) (local.get 0))
+ (func (export "g") (param i32) (result i32) (i32.const 666))
+
+ (elem (i32.const 1) $f)
+)
diff --git a/deps/v8/third_party/wasm-api/example/threads.c b/deps/v8/third_party/wasm-api/example/threads.c
new file mode 100644
index 0000000000..2f5b0f3c1f
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/threads.c
@@ -0,0 +1,152 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include "wasm.h"
+
+#define own
+
+const int N_THREADS = 10;
+const int N_REPS = 3;
+
+// A function to be called from Wasm code.
+own wasm_trap_t* callback(const wasm_val_t args[], wasm_val_t results[]) {
+ assert(args[0].kind == WASM_I32);
+ printf("> Thread %d running\n", args[0].of.i32);
+ return NULL;
+}
+
+
+typedef struct {
+ wasm_engine_t* engine;
+ wasm_shared_module_t* module;
+ int id;
+} thread_args;
+
+void* run(void* args_abs) {
+ thread_args* args = (thread_args*)args_abs;
+
+ // Rereate store and module.
+ own wasm_store_t* store = wasm_store_new(args->engine);
+ own wasm_module_t* module = wasm_module_obtain(store, args->module);
+
+ // Run the example N times.
+ for (int i = 0; i < N_REPS; ++i) {
+ usleep(100000);
+
+ // Create imports.
+ own wasm_functype_t* func_type = wasm_functype_new_1_0(wasm_valtype_new_i32());
+ own wasm_func_t* func = wasm_func_new(store, func_type, callback);
+ wasm_functype_delete(func_type);
+
+ wasm_val_t val = {.kind = WASM_I32, .of = {.i32 = (int32_t)args->id}};
+ own wasm_globaltype_t* global_type =
+ wasm_globaltype_new(wasm_valtype_new_i32(), WASM_CONST);
+ own wasm_global_t* global = wasm_global_new(store, global_type, &val);
+ wasm_globaltype_delete(global_type);
+
+ // Instantiate.
+ const wasm_extern_t* imports[] = {
+ wasm_func_as_extern(func), wasm_global_as_extern(global),
+ };
+ own wasm_instance_t* instance = wasm_instance_new(store, module, imports);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ return NULL;
+ }
+
+ wasm_func_delete(func);
+ wasm_global_delete(global);
+
+ // Extract export.
+ own wasm_extern_vec_t exports;
+ wasm_instance_exports(instance, &exports);
+ if (exports.size == 0) {
+ printf("> Error accessing exports!\n");
+ return NULL;
+ }
+ const wasm_func_t *run_func = wasm_extern_as_func(exports.data[0]);
+ if (run_func == NULL) {
+ printf("> Error accessing export!\n");
+ return NULL;
+ }
+
+ wasm_instance_delete(instance);
+
+ // Call.
+ if (wasm_func_call(run_func, NULL, NULL)) {
+ printf("> Error calling function!\n");
+ return NULL;
+ }
+
+ wasm_extern_vec_delete(&exports);
+ }
+
+ wasm_module_delete(module);
+ wasm_store_delete(store);
+
+ free(args_abs);
+
+ return NULL;
+}
+
+int main(int argc, const char *argv[]) {
+ // Initialize.
+ wasm_engine_t* engine = wasm_engine_new();
+
+ // Load binary.
+ FILE* file = fopen("threads.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile and share.
+ own wasm_store_t* store = wasm_store_new(engine);
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ own wasm_shared_module_t* shared = wasm_module_share(module);
+
+ wasm_module_delete(module);
+ wasm_store_delete(store);
+
+ // Spawn threads.
+ pthread_t threads[N_THREADS];
+ for (int i = 0; i < N_THREADS; i++) {
+ thread_args* args = malloc(sizeof(thread_args));
+ args->id = i;
+ args->engine = engine;
+ args->module = shared;
+ printf("Initializing thread %d...\n", i);
+ pthread_create(&threads[i], NULL, &run, args);
+ }
+
+ for (int i = 0; i < N_THREADS; i++) {
+ printf("Waiting for thread: %d\n", i);
+ pthread_join(threads[i], NULL);
+ }
+
+ wasm_shared_module_delete(shared);
+ wasm_engine_delete(engine);
+
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/threads.cc b/deps/v8/third_party/wasm-api/example/threads.cc
new file mode 100644
index 0000000000..48b4fcd486
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/threads.cc
@@ -0,0 +1,124 @@
+#include <iostream>
+#include <fstream>
+#include <thread>
+#include <mutex>
+
+#include "wasm.hh"
+
+const int N_THREADS = 10;
+const int N_REPS = 3;
+
+// A function to be called from Wasm code.
+auto callback(
+ void* env, const wasm::Val args[], wasm::Val results[]
+) -> wasm::own<wasm::Trap*> {
+ assert(args[0].kind() == wasm::I32);
+ std::lock_guard<std::mutex>(*reinterpret_cast<std::mutex*>(env));
+ std::cout << "Thread " << args[0].i32() << " running..." << std::endl;
+ std::cout.flush();
+ return nullptr;
+}
+
+
+void run(
+ wasm::Engine* engine, const wasm::Shared<wasm::Module>* shared,
+ std::mutex* mutex, int id
+) {
+ // Create store.
+ auto store_ = wasm::Store::make(engine);
+ auto store = store_.get();
+
+ // Obtain.
+ auto module = wasm::Module::obtain(store, shared);
+ if (!module) {
+ std::lock_guard<std::mutex> lock(*mutex);
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Run the example N times.
+ for (int i = 0; i < N_REPS; ++i) {
+ std::this_thread::sleep_for(std::chrono::nanoseconds(100000));
+
+ // Create imports.
+ auto func_type = wasm::FuncType::make(
+ wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32)),
+ wasm::vec<wasm::ValType*>::make()
+ );
+ auto func = wasm::Func::make(store, func_type.get(), callback, mutex);
+
+ auto global_type = wasm::GlobalType::make(
+ wasm::ValType::make(wasm::I32), wasm::CONST);
+ auto global = wasm::Global::make(
+ store, global_type.get(), wasm::Val::i32(i));
+
+ // Instantiate.
+ wasm::Extern* imports[] = {func.get(), global.get()};
+ auto instance = wasm::Instance::make(store, module.get(), imports);
+ if (!instance) {
+ std::lock_guard<std::mutex> lock(*mutex);
+ std::cout << "> Error instantiating module!" << std::endl;
+ return;
+ }
+
+ // Extract export.
+ auto exports = instance->exports();
+ if (exports.size() == 0 || exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func()) {
+ std::lock_guard<std::mutex> lock(*mutex);
+ std::cout << "> Error accessing export!" << std::endl;
+ return;
+ }
+ auto run_func = exports[0]->func();
+
+ // Call.
+ run_func->call();
+ }
+}
+
+int main(int argc, const char *argv[]) {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("threads.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return 1;
+ }
+
+ // Compile and share.
+ std::cout << "Compiling and sharing module..." << std::endl;
+ auto store = wasm::Store::make(engine.get());
+ auto module = wasm::Module::make(store.get(), binary);
+ auto shared = module->share();
+
+ // Spawn threads.
+ std::cout << "Spawning threads..." << std::endl;
+ std::mutex mutex;
+ std::thread threads[N_THREADS];
+ for (int i = 0; i < N_THREADS; ++i) {
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ std::cout << "Initializing thread " << i << "..." << std::endl;
+ }
+ threads[i] = std::thread(run, engine.get(), shared.get(), &mutex, i);
+ }
+
+ for (int i = 0; i < N_THREADS; ++i) {
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ std::cout << "Waiting for thread " << i << "..." << std::endl;
+ }
+ threads[i].join();
+ }
+
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/threads.wasm b/deps/v8/third_party/wasm-api/example/threads.wasm
new file mode 100644
index 0000000000..9a5c19d0ac
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/threads.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/threads.wat b/deps/v8/third_party/wasm-api/example/threads.wat
new file mode 100644
index 0000000000..29a3bbcc1a
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/threads.wat
@@ -0,0 +1,5 @@
+(module
+ (func $message (import "" "hello") (param i32))
+ (global $id (import "" "id") i32)
+ (func (export "run") (call $message (global.get $id)))
+)
diff --git a/deps/v8/third_party/wasm-api/example/trap.c b/deps/v8/third_party/wasm-api/example/trap.c
new file mode 100644
index 0000000000..74620dce3b
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/trap.c
@@ -0,0 +1,121 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "wasm.h"
+
+#define own
+
+// A function to be called from Wasm code.
+own wasm_trap_t* fail_callback(
+ void* env, const wasm_val_t args[], wasm_val_t results[]
+) {
+ printf("Calling back...\n");
+ own wasm_name_t message;
+ wasm_name_new_from_string(&message, "callback abort");
+ own wasm_trap_t* trap = wasm_trap_new((wasm_store_t*)env, &message);
+ wasm_name_delete(&message);
+ return trap;
+}
+
+
+int main(int argc, const char* argv[]) {
+ // Initialize.
+ printf("Initializing...\n");
+ wasm_engine_t* engine = wasm_engine_new();
+ wasm_store_t* store = wasm_store_new(engine);
+
+ // Load binary.
+ printf("Loading binary...\n");
+ FILE* file = fopen("trap.wasm", "r");
+ if (!file) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fseek(file, 0L, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+ wasm_byte_vec_t binary;
+ wasm_byte_vec_new_uninitialized(&binary, file_size);
+ if (fread(binary.data, file_size, 1, file) != 1) {
+ printf("> Error loading module!\n");
+ return 1;
+ }
+ fclose(file);
+
+ // Compile.
+ printf("Compiling module...\n");
+ own wasm_module_t* module = wasm_module_new(store, &binary);
+ if (!module) {
+ printf("> Error compiling module!\n");
+ return 1;
+ }
+
+ wasm_byte_vec_delete(&binary);
+
+ // Create external print functions.
+ printf("Creating callback...\n");
+ own wasm_functype_t* fail_type = wasm_functype_new_0_1(wasm_valtype_new_i32());
+ own wasm_func_t* fail_func = wasm_func_new_with_env(store, fail_type, fail_callback, store, NULL);
+
+ wasm_functype_delete(fail_type);
+
+ // Instantiate.
+ printf("Instantiating module...\n");
+ const wasm_extern_t* imports[] = { wasm_func_as_extern(fail_func) };
+ own wasm_instance_t* instance = wasm_instance_new(store, module, imports);
+ if (!instance) {
+ printf("> Error instantiating module!\n");
+ return 1;
+ }
+
+ wasm_func_delete(fail_func);
+
+ // Extract export.
+ printf("Extracting exports...\n");
+ own wasm_extern_vec_t exports;
+ wasm_instance_exports(instance, &exports);
+ if (exports.size < 2) {
+ printf("> Error accessing exports!\n");
+ return 1;
+ }
+
+ wasm_module_delete(module);
+ wasm_instance_delete(instance);
+
+ // Call.
+ for (int i = 0; i < 2; ++i) {
+ const wasm_func_t* func = wasm_extern_as_func(exports.data[i]);
+ if (func == NULL) {
+ printf("> Error accessing export!\n");
+ return 1;
+ }
+
+ printf("Calling export %d...\n", i);
+ own wasm_trap_t* trap = wasm_func_call(func, NULL, NULL);
+ if (! trap) {
+ printf("> Error calling function!\n");
+ return 1;
+ }
+
+ printf("Printing message...\n");
+ own wasm_name_t message;
+ wasm_trap_message(trap, &message);
+ printf("> %s\n", message.data);
+
+ wasm_trap_delete(trap);
+ wasm_name_delete(&message);
+ }
+
+ wasm_extern_vec_delete(&exports);
+
+ // Shut down.
+ printf("Shutting down...\n");
+ wasm_store_delete(store);
+ wasm_engine_delete(engine);
+
+ // All done.
+ printf("Done.\n");
+ return 0;
+}
diff --git a/deps/v8/third_party/wasm-api/example/trap.cc b/deps/v8/third_party/wasm-api/example/trap.cc
new file mode 100644
index 0000000000..3311621724
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/trap.cc
@@ -0,0 +1,100 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <string>
+#include <cinttypes>
+
+#include "wasm.hh"
+
+// A function to be called from Wasm code.
+auto fail_callback(
+ void* env, const wasm::Val args[], wasm::Val results[]
+) -> wasm::own<wasm::Trap*> {
+ std::cout << "Calling back..." << std::endl;
+ auto store = reinterpret_cast<wasm::Store*>(env);
+ auto message = wasm::Name::make(std::string("callback abort"));
+ return wasm::Trap::make(store, message);
+}
+
+
+void run() {
+ // Initialize.
+ std::cout << "Initializing..." << std::endl;
+ auto engine = wasm::Engine::make();
+ auto store_ = wasm::Store::make(engine.get());
+ auto store = store_.get();
+
+ // Load binary.
+ std::cout << "Loading binary..." << std::endl;
+ std::ifstream file("trap.wasm");
+ file.seekg(0, std::ios_base::end);
+ auto file_size = file.tellg();
+ file.seekg(0);
+ auto binary = wasm::vec<byte_t>::make_uninitialized(file_size);
+ file.read(binary.get(), file_size);
+ file.close();
+ if (file.fail()) {
+ std::cout << "> Error loading module!" << std::endl;
+ return;
+ }
+
+ // Compile.
+ std::cout << "Compiling module..." << std::endl;
+ auto module = wasm::Module::make(store, binary);
+ if (!module) {
+ std::cout << "> Error compiling module!" << std::endl;
+ return;
+ }
+
+ // Create external print functions.
+ std::cout << "Creating callback..." << std::endl;
+ auto fail_type = wasm::FuncType::make(
+ wasm::vec<wasm::ValType*>::make(),
+ wasm::vec<wasm::ValType*>::make(wasm::ValType::make(wasm::I32))
+ );
+ auto fail_func =
+ wasm::Func::make(store, fail_type.get(), fail_callback, store);
+
+ // Instantiate.
+ std::cout << "Instantiating module..." << std::endl;
+ wasm::Extern* imports[] = {fail_func.get()};
+ auto instance = wasm::Instance::make(store, module.get(), imports);
+ if (!instance) {
+ std::cout << "> Error instantiating module!" << std::endl;
+ return;
+ }
+
+ // Extract export.
+ std::cout << "Extracting exports..." << std::endl;
+ auto exports = instance->exports();
+ if (exports.size() < 2 ||
+ exports[0]->kind() != wasm::EXTERN_FUNC || !exports[0]->func() ||
+ exports[1]->kind() != wasm::EXTERN_FUNC || !exports[1]->func()) {
+ std::cout << "> Error accessing exports!" << std::endl;
+ return;
+ }
+
+ // Call.
+ for (size_t i = 0; i < 2; ++i) {
+ std::cout << "Calling export " << i << "..." << std::endl;
+ auto trap = exports[i]->func()->call();
+ if (!trap) {
+ std::cout << "> Error calling function!" << std::endl;
+ return;
+ }
+
+ std::cout << "Printing message..." << std::endl;
+ std::cout << "> " << trap->message().get() << std::endl;
+ }
+
+ // Shut down.
+ std::cout << "Shutting down..." << std::endl;
+}
+
+
+int main(int argc, const char* argv[]) {
+ run();
+ std::cout << "Done." << std::endl;
+ return 0;
+}
+
diff --git a/deps/v8/third_party/wasm-api/example/trap.wasm b/deps/v8/third_party/wasm-api/example/trap.wasm
new file mode 100644
index 0000000000..eeed14c897
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/trap.wasm
Binary files differ
diff --git a/deps/v8/third_party/wasm-api/example/trap.wat b/deps/v8/third_party/wasm-api/example/trap.wat
new file mode 100644
index 0000000000..dfd20fb12a
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/example/trap.wat
@@ -0,0 +1,5 @@
+(module
+ (func $callback (import "" "callback") (result i32))
+ (func (export "callback") (result i32) (call $callback))
+ (func (export "unreachable") (result i32) (unreachable) (i32.const 1))
+)
diff --git a/deps/v8/third_party/wasm-api/wasm.h b/deps/v8/third_party/wasm-api/wasm.h
new file mode 100644
index 0000000000..bb66c042d9
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/wasm.h
@@ -0,0 +1,677 @@
+// WebAssembly C API
+
+#ifndef __WASM_H
+#define __WASM_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Auxiliaries
+
+// Machine types
+
+inline void assertions() {
+ static_assert(sizeof(float) == sizeof(uint32_t), "incompatible float type");
+ static_assert(sizeof(double) == sizeof(uint64_t), "incompatible double type");
+ static_assert(sizeof(intptr_t) == sizeof(uint32_t) ||
+ sizeof(intptr_t) == sizeof(uint64_t),
+ "incompatible pointer type");
+}
+
+typedef char byte_t;
+typedef float float32_t;
+typedef double float64_t;
+
+
+// Ownership
+
+#define own
+
+// The qualifier `own` is used to indicate ownership of data in this API.
+// It is intended to be interpreted similar to a `const` qualifier:
+//
+// - `own wasm_xxx_t*` owns the pointed-to data
+// - `own wasm_xxx_t` distributes to all fields of a struct or union `xxx`
+// - `own wasm_xxx_vec_t` owns the vector as well as its elements(!)
+// - an `own` function parameter passes ownership from caller to callee
+// - an `own` function result passes ownership from callee to caller
+// - an exception are `own` pointer parameters named `out`, which are copy-back
+// output parameters passing back ownership from callee to caller
+//
+// Own data is created by `wasm_xxx_new` functions and some others.
+// It must be released with the corresponding `wasm_xxx_delete` function.
+//
+// Deleting a reference does not necessarily delete the underlying object,
+// it merely indicates that this owner no longer uses it.
+//
+// For vectors, `const wasm_xxx_vec_t` is used informally to indicate that
+// neither the vector nor its elements should be modified.
+// TODO: introduce proper `wasm_xxx_const_vec_t`?
+
+
+#define WASM_DECLARE_OWN(name) \
+ typedef struct wasm_##name##_t wasm_##name##_t; \
+ \
+ void wasm_##name##_delete(own wasm_##name##_t*);
+
+
+// Vectors
+
+#define WASM_DECLARE_VEC(name, ptr_or_none) \
+ typedef struct wasm_##name##_vec_t { \
+ size_t size; \
+ wasm_##name##_t ptr_or_none* data; \
+ } wasm_##name##_vec_t; \
+ \
+ void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \
+ void wasm_##name##_vec_new_uninitialized( \
+ own wasm_##name##_vec_t* out, size_t); \
+ void wasm_##name##_vec_new( \
+ own wasm_##name##_vec_t* out, \
+ size_t, own wasm_##name##_t ptr_or_none const[]); \
+ void wasm_##name##_vec_copy( \
+ own wasm_##name##_vec_t* out, wasm_##name##_vec_t*); \
+ void wasm_##name##_vec_delete(own wasm_##name##_vec_t*);
+
+
+// Byte vectors
+
+typedef byte_t wasm_byte_t;
+WASM_DECLARE_VEC(byte, )
+
+typedef wasm_byte_vec_t wasm_name_t;
+
+#define wasm_name wasm_byte_vec
+#define wasm_name_new wasm_byte_vec_new
+#define wasm_name_new_empty wasm_byte_vec_new_empty
+#define wasm_name_new_new_uninitialized wasm_byte_vec_new_uninitialized
+#define wasm_name_copy wasm_byte_vec_copy
+#define wasm_name_delete wasm_byte_vec_delete
+
+static inline void wasm_name_new_from_string(
+ own wasm_name_t* out, const char* s
+) {
+ wasm_name_new(out, strlen(s) + 1, s);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Runtime Environment
+
+// Configuration
+
+WASM_DECLARE_OWN(config)
+
+own wasm_config_t* wasm_config_new();
+
+// Embedders may provide custom functions for manipulating configs.
+
+
+// Engine
+
+WASM_DECLARE_OWN(engine)
+
+own wasm_engine_t* wasm_engine_new();
+own wasm_engine_t* wasm_engine_new_with_config(own wasm_config_t*);
+
+
+// Store
+
+WASM_DECLARE_OWN(store)
+
+own wasm_store_t* wasm_store_new(wasm_engine_t*);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Type Representations
+
+// Type attributes
+
+typedef enum wasm_mutability_t {
+ WASM_CONST,
+ WASM_VAR
+} wasm_mutability_t;
+
+typedef struct wasm_limits_t {
+ uint32_t min;
+ uint32_t max;
+} wasm_limits_t;
+
+static const uint32_t wasm_limits_max_default = 0xffffffff;
+
+
+// Generic
+
+#define WASM_DECLARE_TYPE(name) \
+ WASM_DECLARE_OWN(name) \
+ WASM_DECLARE_VEC(name, *) \
+ \
+ own wasm_##name##_t* wasm_##name##_copy(wasm_##name##_t*);
+
+
+// Value Types
+
+WASM_DECLARE_TYPE(valtype)
+
+typedef enum wasm_valkind_t {
+ WASM_I32,
+ WASM_I64,
+ WASM_F32,
+ WASM_F64,
+ WASM_ANYREF,
+ WASM_FUNCREF
+} wasm_valkind_t;
+
+own wasm_valtype_t* wasm_valtype_new(wasm_valkind_t);
+
+wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t*);
+
+static inline bool wasm_valkind_is_num(wasm_valkind_t k) {
+ return k < WASM_ANYREF;
+}
+static inline bool wasm_valkind_is_ref(wasm_valkind_t k) {
+ return k >= WASM_ANYREF;
+}
+
+static inline bool wasm_valtype_is_num(const wasm_valtype_t* t) {
+ return wasm_valkind_is_num(wasm_valtype_kind(t));
+}
+static inline bool wasm_valtype_is_ref(const wasm_valtype_t* t) {
+ return wasm_valkind_is_ref(wasm_valtype_kind(t));
+}
+
+
+// Function Types
+
+WASM_DECLARE_TYPE(functype)
+
+own wasm_functype_t* wasm_functype_new(
+ own wasm_valtype_vec_t* params, own wasm_valtype_vec_t* results);
+
+const wasm_valtype_vec_t* wasm_functype_params(const wasm_functype_t*);
+const wasm_valtype_vec_t* wasm_functype_results(const wasm_functype_t*);
+
+
+// Global Types
+
+WASM_DECLARE_TYPE(globaltype)
+
+own wasm_globaltype_t* wasm_globaltype_new(
+ own wasm_valtype_t*, wasm_mutability_t);
+
+const wasm_valtype_t* wasm_globaltype_content(const wasm_globaltype_t*);
+wasm_mutability_t wasm_globaltype_mutability(const wasm_globaltype_t*);
+
+
+// Table Types
+
+WASM_DECLARE_TYPE(tabletype)
+
+own wasm_tabletype_t* wasm_tabletype_new(
+ own wasm_valtype_t*, const wasm_limits_t*);
+
+const wasm_valtype_t* wasm_tabletype_element(const wasm_tabletype_t*);
+const wasm_limits_t* wasm_tabletype_limits(const wasm_tabletype_t*);
+
+
+// Memory Types
+
+WASM_DECLARE_TYPE(memorytype)
+
+own wasm_memorytype_t* wasm_memorytype_new(const wasm_limits_t*);
+
+const wasm_limits_t* wasm_memorytype_limits(const wasm_memorytype_t*);
+
+
+// Extern Types
+
+WASM_DECLARE_TYPE(externtype)
+
+typedef enum wasm_externkind_t {
+ WASM_EXTERN_FUNC,
+ WASM_EXTERN_GLOBAL,
+ WASM_EXTERN_TABLE,
+ WASM_EXTERN_MEMORY
+} wasm_externkind_t;
+
+wasm_externkind_t wasm_externtype_kind(const wasm_externtype_t*);
+
+wasm_externtype_t* wasm_functype_as_externtype(wasm_functype_t*);
+wasm_externtype_t* wasm_globaltype_as_externtype(wasm_globaltype_t*);
+wasm_externtype_t* wasm_tabletype_as_externtype(wasm_tabletype_t*);
+wasm_externtype_t* wasm_memorytype_as_externtype(wasm_memorytype_t*);
+
+wasm_functype_t* wasm_externtype_as_functype(wasm_externtype_t*);
+wasm_globaltype_t* wasm_externtype_as_globaltype(wasm_externtype_t*);
+wasm_tabletype_t* wasm_externtype_as_tabletype(wasm_externtype_t*);
+wasm_memorytype_t* wasm_externtype_as_memorytype(wasm_externtype_t*);
+
+const wasm_externtype_t* wasm_functype_as_externtype_const(const wasm_functype_t*);
+const wasm_externtype_t* wasm_globaltype_as_externtype_const(const wasm_globaltype_t*);
+const wasm_externtype_t* wasm_tabletype_as_externtype_const(const wasm_tabletype_t*);
+const wasm_externtype_t* wasm_memorytype_as_externtype_const(const wasm_memorytype_t*);
+
+const wasm_functype_t* wasm_externtype_as_functype_const(const wasm_externtype_t*);
+const wasm_globaltype_t* wasm_externtype_as_globaltype_const(const wasm_externtype_t*);
+const wasm_tabletype_t* wasm_externtype_as_tabletype_const(const wasm_externtype_t*);
+const wasm_memorytype_t* wasm_externtype_as_memorytype_const(const wasm_externtype_t*);
+
+
+// Import Types
+
+WASM_DECLARE_TYPE(importtype)
+
+own wasm_importtype_t* wasm_importtype_new(
+ own wasm_name_t* module, own wasm_name_t* name, own wasm_externtype_t*);
+
+const wasm_name_t* wasm_importtype_module(const wasm_importtype_t*);
+const wasm_name_t* wasm_importtype_name(const wasm_importtype_t*);
+const wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t*);
+
+
+// Export Types
+
+WASM_DECLARE_TYPE(exporttype)
+
+own wasm_exporttype_t* wasm_exporttype_new(
+ own wasm_name_t*, own wasm_externtype_t*);
+
+const wasm_name_t* wasm_exporttype_name(const wasm_exporttype_t*);
+const wasm_externtype_t* wasm_exporttype_type(const wasm_exporttype_t*);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Runtime Objects
+
+// Values
+
+struct wasm_ref_t;
+
+typedef struct wasm_val_t {
+ wasm_valkind_t kind;
+ union {
+ int32_t i32;
+ int64_t i64;
+ float32_t f32;
+ float64_t f64;
+ struct wasm_ref_t* ref;
+ } of;
+} wasm_val_t;
+
+void wasm_val_delete(own wasm_val_t* v);
+void wasm_val_copy(own wasm_val_t* out, const wasm_val_t*);
+
+WASM_DECLARE_VEC(val, )
+
+
+// References
+
+#define WASM_DECLARE_REF_BASE(name) \
+ WASM_DECLARE_OWN(name) \
+ \
+ own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*); \
+ \
+ void* wasm_##name##_get_host_info(const wasm_##name##_t*); \
+ void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \
+ void wasm_##name##_set_host_info_with_finalizer( \
+ wasm_##name##_t*, void*, void (*)(void*));
+
+#define WASM_DECLARE_REF(name) \
+ WASM_DECLARE_REF_BASE(name) \
+ \
+ wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \
+ wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \
+ const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t*); \
+ const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t*);
+
+#define WASM_DECLARE_SHARABLE_REF(name) \
+ WASM_DECLARE_REF(name) \
+ WASM_DECLARE_OWN(shared_##name) \
+ \
+ own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*); \
+ own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*);
+
+
+WASM_DECLARE_REF_BASE(ref)
+
+
+// Traps
+
+typedef wasm_name_t wasm_message_t; // null terminated
+
+WASM_DECLARE_REF(trap)
+
+own wasm_trap_t* wasm_trap_new(wasm_store_t* store, const wasm_message_t*);
+
+void wasm_trap_message(const wasm_trap_t*, own wasm_message_t* out);
+
+
+// Foreign Objects
+
+WASM_DECLARE_REF(foreign)
+
+own wasm_foreign_t* wasm_foreign_new(wasm_store_t*);
+
+
+// Modules
+
+WASM_DECLARE_SHARABLE_REF(module)
+
+own wasm_module_t* wasm_module_new(
+ wasm_store_t*, const wasm_byte_vec_t* binary);
+
+bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary);
+
+void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out);
+void wasm_module_exports(const wasm_module_t*, own wasm_exporttype_vec_t* out);
+
+void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
+own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*);
+
+
+// Function Instances
+
+WASM_DECLARE_REF(func)
+
+typedef own wasm_trap_t* (*wasm_func_callback_t)(
+ const wasm_val_t args[], wasm_val_t results[]);
+typedef own wasm_trap_t* (*wasm_func_callback_with_env_t)(
+ void* env, const wasm_val_t args[], wasm_val_t results[]);
+
+own wasm_func_t* wasm_func_new(
+ wasm_store_t*, const wasm_functype_t*, wasm_func_callback_t);
+own wasm_func_t* wasm_func_new_with_env(
+ wasm_store_t*, const wasm_functype_t* type, wasm_func_callback_with_env_t,
+ void* env, void (*finalizer)(void*));
+
+own wasm_functype_t* wasm_func_type(const wasm_func_t*);
+size_t wasm_func_param_arity(const wasm_func_t*);
+size_t wasm_func_result_arity(const wasm_func_t*);
+
+own wasm_trap_t* wasm_func_call(
+ const wasm_func_t*, const wasm_val_t args[], wasm_val_t results[]);
+
+
+// Global Instances
+
+WASM_DECLARE_REF(global)
+
+own wasm_global_t* wasm_global_new(
+ wasm_store_t*, const wasm_globaltype_t*, const wasm_val_t*);
+
+own wasm_globaltype_t* wasm_global_type(const wasm_global_t*);
+
+void wasm_global_get(const wasm_global_t*, own wasm_val_t* out);
+void wasm_global_set(wasm_global_t*, const wasm_val_t*);
+
+
+// Table Instances
+
+WASM_DECLARE_REF(table)
+
+typedef uint32_t wasm_table_size_t;
+
+own wasm_table_t* wasm_table_new(
+ wasm_store_t*, const wasm_tabletype_t*, wasm_ref_t* init);
+
+own wasm_tabletype_t* wasm_table_type(const wasm_table_t*);
+
+own wasm_ref_t* wasm_table_get(const wasm_table_t*, wasm_table_size_t index);
+bool wasm_table_set(wasm_table_t*, wasm_table_size_t index, wasm_ref_t*);
+
+wasm_table_size_t wasm_table_size(const wasm_table_t*);
+bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init);
+
+
+// Memory Instances
+
+WASM_DECLARE_REF(memory)
+
+typedef uint32_t wasm_memory_pages_t;
+
+static const size_t MEMORY_PAGE_SIZE = 0x10000;
+
+own wasm_memory_t* wasm_memory_new(wasm_store_t*, const wasm_memorytype_t*);
+
+own wasm_memorytype_t* wasm_memory_type(const wasm_memory_t*);
+
+byte_t* wasm_memory_data(wasm_memory_t*);
+size_t wasm_memory_data_size(const wasm_memory_t*);
+
+wasm_memory_pages_t wasm_memory_size(const wasm_memory_t*);
+bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta);
+
+
+// Externals
+
+WASM_DECLARE_REF(extern)
+WASM_DECLARE_VEC(extern, *)
+
+wasm_externkind_t wasm_extern_kind(const wasm_extern_t*);
+own wasm_externtype_t* wasm_extern_type(const wasm_extern_t*);
+
+wasm_extern_t* wasm_func_as_extern(wasm_func_t*);
+wasm_extern_t* wasm_global_as_extern(wasm_global_t*);
+wasm_extern_t* wasm_table_as_extern(wasm_table_t*);
+wasm_extern_t* wasm_memory_as_extern(wasm_memory_t*);
+
+wasm_func_t* wasm_extern_as_func(wasm_extern_t*);
+wasm_global_t* wasm_extern_as_global(wasm_extern_t*);
+wasm_table_t* wasm_extern_as_table(wasm_extern_t*);
+wasm_memory_t* wasm_extern_as_memory(wasm_extern_t*);
+
+const wasm_extern_t* wasm_func_as_extern_const(const wasm_func_t*);
+const wasm_extern_t* wasm_global_as_extern_const(const wasm_global_t*);
+const wasm_extern_t* wasm_table_as_extern_const(const wasm_table_t*);
+const wasm_extern_t* wasm_memory_as_extern_const(const wasm_memory_t*);
+
+const wasm_func_t* wasm_extern_as_func_const(const wasm_extern_t*);
+const wasm_global_t* wasm_extern_as_global_const(const wasm_extern_t*);
+const wasm_table_t* wasm_extern_as_table_const(const wasm_extern_t*);
+const wasm_memory_t* wasm_extern_as_memory_const(const wasm_extern_t*);
+
+
+// Module Instances
+
+WASM_DECLARE_REF(instance)
+
+own wasm_instance_t* wasm_instance_new(
+ wasm_store_t*, const wasm_module_t*, const wasm_extern_t* const imports[]);
+
+void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Convenience
+
+// Value Type construction short-hands
+
+static inline own wasm_valtype_t* wasm_valtype_new_i32() {
+ return wasm_valtype_new(WASM_I32);
+}
+static inline own wasm_valtype_t* wasm_valtype_new_i64() {
+ return wasm_valtype_new(WASM_I64);
+}
+static inline own wasm_valtype_t* wasm_valtype_new_f32() {
+ return wasm_valtype_new(WASM_F32);
+}
+static inline own wasm_valtype_t* wasm_valtype_new_f64() {
+ return wasm_valtype_new(WASM_F64);
+}
+
+static inline own wasm_valtype_t* wasm_valtype_new_anyref() {
+ return wasm_valtype_new(WASM_ANYREF);
+}
+static inline own wasm_valtype_t* wasm_valtype_new_funcref() {
+ return wasm_valtype_new(WASM_FUNCREF);
+}
+
+
+// Function Types construction short-hands
+
+static inline own wasm_functype_t* wasm_functype_new_0_0() {
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new_empty(&params);
+ wasm_valtype_vec_new_empty(&results);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_1_0(
+ own wasm_valtype_t* p
+) {
+ wasm_valtype_t* ps[1] = {p};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(&params, 1, ps);
+ wasm_valtype_vec_new_empty(&results);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_2_0(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2
+) {
+ wasm_valtype_t* ps[2] = {p1, p2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(&params, 2, ps);
+ wasm_valtype_vec_new_empty(&results);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_3_0(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3
+) {
+ wasm_valtype_t* ps[3] = {p1, p2, p3};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(&params, 3, ps);
+ wasm_valtype_vec_new_empty(&results);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_0_1(
+ own wasm_valtype_t* r
+) {
+ wasm_valtype_t* rs[1] = {r};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new_empty(&params);
+ wasm_valtype_vec_new(&results, 1, rs);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_1_1(
+ own wasm_valtype_t* p, own wasm_valtype_t* r
+) {
+ wasm_valtype_t* ps[1] = {p};
+ wasm_valtype_t* rs[1] = {r};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(&params, 1, ps);
+ wasm_valtype_vec_new(&results, 1, rs);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_2_1(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* r
+) {
+ wasm_valtype_t* ps[2] = {p1, p2};
+ wasm_valtype_t* rs[1] = {r};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(&params, 2, ps);
+ wasm_valtype_vec_new(&results, 1, rs);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_3_1(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3,
+ own wasm_valtype_t* r
+) {
+ wasm_valtype_t* ps[3] = {p1, p2, p3};
+ wasm_valtype_t* rs[1] = {r};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(&params, 3, ps);
+ wasm_valtype_vec_new(&results, 1, rs);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_0_2(
+ own wasm_valtype_t* r1, own wasm_valtype_t* r2
+) {
+ wasm_valtype_t* rs[2] = {r1, r2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new_empty(&params);
+ wasm_valtype_vec_new(&results, 2, rs);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_1_2(
+ own wasm_valtype_t* p, own wasm_valtype_t* r1, own wasm_valtype_t* r2
+) {
+ wasm_valtype_t* ps[1] = {p};
+ wasm_valtype_t* rs[2] = {r1, r2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(&params, 1, ps);
+ wasm_valtype_vec_new(&results, 2, rs);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_2_2(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2,
+ own wasm_valtype_t* r1, own wasm_valtype_t* r2
+) {
+ wasm_valtype_t* ps[2] = {p1, p2};
+ wasm_valtype_t* rs[2] = {r1, r2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(&params, 2, ps);
+ wasm_valtype_vec_new(&results, 2, rs);
+ return wasm_functype_new(&params, &results);
+}
+
+static inline own wasm_functype_t* wasm_functype_new_3_2(
+ own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3,
+ own wasm_valtype_t* r1, own wasm_valtype_t* r2
+) {
+ wasm_valtype_t* ps[3] = {p1, p2, p3};
+ wasm_valtype_t* rs[2] = {r1, r2};
+ wasm_valtype_vec_t params, results;
+ wasm_valtype_vec_new(&params, 3, ps);
+ wasm_valtype_vec_new(&results, 2, rs);
+ return wasm_functype_new(&params, &results);
+}
+
+
+// Value construction short-hands
+
+static inline void wasm_val_init_ptr(own wasm_val_t* out, void* p) {
+#if UINTPTR_MAX == UINT32_MAX
+ out->kind = WASM_I32;
+ out->of.i32 = (intptr_t)p;
+#elif UINTPTR_MAX == UINT64_MAX
+ out->kind = WASM_I64;
+ out->of.i64 = (intptr_t)p;
+#endif
+}
+
+static inline void* wasm_val_ptr(const wasm_val_t* val) {
+#if UINTPTR_MAX == UINT32_MAX
+ return (void*)(intptr_t)val->of.i32;
+#elif UINTPTR_MAX == UINT64_MAX
+ return (void*)(intptr_t)val->of.i64;
+#endif
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+#undef own
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // #ifdef __WASM_H
diff --git a/deps/v8/third_party/wasm-api/wasm.hh b/deps/v8/third_party/wasm-api/wasm.hh
new file mode 100644
index 0000000000..c153d4b9df
--- /dev/null
+++ b/deps/v8/third_party/wasm-api/wasm.hh
@@ -0,0 +1,770 @@
+// WebAssembly C++ API
+
+#ifndef __WASM_HH
+#define __WASM_HH
+
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <memory>
+#include <limits>
+#include <string>
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Auxiliaries
+
+// Machine types
+
+static_assert(sizeof(float) == sizeof(int32_t), "incompatible float type");
+static_assert(sizeof(double) == sizeof(int64_t), "incompatible double type");
+static_assert(sizeof(intptr_t) == sizeof(int32_t) ||
+ sizeof(intptr_t) == sizeof(int64_t), "incompatible pointer type");
+
+using byte_t = char;
+using float32_t = float;
+using float64_t = double;
+
+
+namespace wasm {
+
+// Ownership
+
+template<class T> struct owner { using type = T; };
+template<class T> struct owner<T*> { using type = std::unique_ptr<T>; };
+
+template<class T>
+using own = typename owner<T>::type;
+
+template<class T>
+auto make_own(T x) -> own<T> { return own<T>(std::move(x)); }
+
+
+// Vectors
+
+template<class T>
+struct vec_traits {
+ static void construct(size_t size, T data[]) {}
+ static void destruct(size_t size, T data[]) {}
+ static void move(size_t size, T* data, T init[]) {
+ for (size_t i = 0; i < size; ++i) data[i] = std::move(init[i]);
+ }
+ static void copy(size_t size, T data[], const T init[]) {
+ for (size_t i = 0; i < size; ++i) data[i] = init[i];
+ }
+
+ using proxy = T&;
+};
+
+template<class T>
+struct vec_traits<T*> {
+ static void construct(size_t size, T* data[]) {
+ for (size_t i = 0; i < size; ++i) data[i] = nullptr;
+ }
+ static void destruct(size_t size, T* data[]) {
+ for (size_t i = 0; i < size; ++i) {
+ if (data[i]) delete data[i];
+ }
+ }
+ static void move(size_t size, T* data[], own<T*> init[]) {
+ for (size_t i = 0; i < size; ++i) data[i] = init[i].release();
+ }
+ static void copy(size_t size, T* data[], const T* const init[]) {
+ for (size_t i = 0; i < size; ++i) {
+ if (init[i]) data[i] = init[i]->copy().release();
+ }
+ }
+
+ class proxy {
+ T*& elem_;
+ public:
+ proxy(T*& elem) : elem_(elem) {}
+ operator T*() { return elem_; }
+ operator const T*() const { return elem_; }
+ auto operator=(own<T*>&& elem) -> proxy& {
+ reset(std::move(elem));
+ return *this;
+ }
+ void reset(own<T*>&& val = own<T*>()) {
+ if (elem_) delete elem_;
+ elem_ = val.release();
+ }
+ auto release() -> T* {
+ auto elem = elem_;
+ elem_ = nullptr;
+ return elem;
+ }
+ auto move() -> own<T*> { return make_own(release()); }
+ auto get() -> T* { return elem_; }
+ auto get() const -> const T* { return elem_; }
+ auto operator->() -> T* { return elem_; }
+ auto operator->() const -> const T* { return elem_; }
+ };
+};
+
+
+template<class T>
+class vec {
+ static const size_t invalid_size = SIZE_MAX;
+
+ size_t size_;
+ std::unique_ptr<T[]> data_;
+
+#ifdef DEBUG
+ void make_data();
+ void free_data();
+#else
+ void make_data() {}
+ void free_data() {}
+#endif
+
+ vec(size_t size) : vec(size, size ? new(std::nothrow) T[size] : nullptr) {
+ make_data();
+ }
+
+ vec(size_t size, T* data) : size_(size), data_(data) {
+ assert(!!size_ == !!data_ || size_ == invalid_size);
+ }
+
+public:
+ template<class U>
+ vec(vec<U>&& that) : vec(that.size_, that.data_.release()) {}
+
+ ~vec() {
+ if (data_) vec_traits<T>::destruct(size_, data_.get());
+ free_data();
+ }
+
+ operator bool() const {
+ return bool(size_ != invalid_size);
+ }
+
+ auto size() const -> size_t {
+ return size_;
+ }
+
+ auto get() const -> const T* {
+ return data_.get();
+ }
+
+ auto get() -> T* {
+ return data_.get();
+ }
+
+ auto release() -> T* {
+ return data_.release();
+ }
+
+ void reset() {
+ if (data_) vec_traits<T>::destruct(size_, data_.get());
+ free_data();
+ size_ = 0;
+ data_.reset();
+ }
+
+ void reset(vec& that) {
+ reset();
+ size_ = that.size_;
+ data_.reset(that.data_.release());
+ }
+
+ auto operator=(vec&& that) -> vec& {
+ reset(that);
+ return *this;
+ }
+
+ auto operator[](size_t i) -> typename vec_traits<T>::proxy {
+ assert(i < size_);
+ return typename vec_traits<T>::proxy(data_[i]);
+ }
+
+ auto operator[](size_t i) const -> const typename vec_traits<T>::proxy {
+ assert(i < size_);
+ return typename vec_traits<T>::proxy(data_[i]);
+ }
+
+ auto copy() const -> vec {
+ auto v = vec(size_);
+ if (v) vec_traits<T>::copy(size_, v.data_.get(), data_.get());
+ return v;
+ }
+
+ static auto make_uninitialized(size_t size = 0) -> vec {
+ auto v = vec(size);
+ if (v) vec_traits<T>::construct(size, v.data_.get());
+ return v;
+ }
+
+ static auto make(size_t size, own<T> init[]) -> vec {
+ auto v = vec(size);
+ if (v) vec_traits<T>::move(size, v.data_.get(), init);
+ return v;
+ }
+
+ static auto make(std::string s) -> vec<char> {
+ auto v = vec(s.length() + 1);
+ if (v) std::strcpy(v.get(), s.data());
+ return v;
+ }
+
+ static auto make() -> vec {
+ return vec(0);
+ }
+
+ template<class... Ts>
+ static auto make(Ts&&... args) -> vec {
+ own<T> data[] = { make_own(std::move(args))... };
+ return make(sizeof...(Ts), data);
+ }
+
+ static auto adopt(size_t size, T data[]) -> vec {
+ return vec(size, data);
+ }
+
+ static auto invalid() -> vec {
+ return vec(invalid_size, nullptr);
+ }
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Runtime Environment
+
+// Configuration
+
+class Config {
+public:
+ Config() = delete;
+ ~Config();
+ void operator delete(void*);
+
+ static auto make() -> own<Config*>;
+
+ // Implementations may provide custom methods for manipulating Configs.
+};
+
+
+// Engine
+
+class Engine {
+public:
+ Engine() = delete;
+ ~Engine();
+ void operator delete(void*);
+
+ static auto make(own<Config*>&& = Config::make()) -> own<Engine*>;
+};
+
+
+// Store
+
+class Store {
+public:
+ Store() = delete;
+ ~Store();
+ void operator delete(void*);
+
+ static auto make(Engine*) -> own<Store*>;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Type Representations
+
+// Type attributes
+
+enum Mutability { CONST, VAR };
+
+struct Limits {
+ uint32_t min;
+ uint32_t max;
+
+ Limits(uint32_t min, uint32_t max = std::numeric_limits<uint32_t>::max()) :
+ min(min), max(max) {}
+};
+
+
+// Value Types
+
+enum ValKind { I32, I64, F32, F64, ANYREF, FUNCREF };
+
+inline bool is_num(ValKind k) { return k < ANYREF; }
+inline bool is_ref(ValKind k) { return k >= ANYREF; }
+
+
+class ValType {
+public:
+ ValType() = delete;
+ ~ValType();
+ void operator delete(void*);
+
+ static auto make(ValKind) -> own<ValType*>;
+ auto copy() const -> own<ValType*>;
+
+ auto kind() const -> ValKind;
+ auto is_num() const -> bool { return wasm::is_num(kind()); }
+ auto is_ref() const -> bool { return wasm::is_ref(kind()); }
+};
+
+
+// External Types
+
+enum ExternKind {
+ EXTERN_FUNC, EXTERN_GLOBAL, EXTERN_TABLE, EXTERN_MEMORY
+};
+
+class FuncType;
+class GlobalType;
+class TableType;
+class MemoryType;
+
+class ExternType {
+public:
+ ExternType() = delete;
+ ~ExternType();
+ void operator delete(void*);
+
+ auto copy() const-> own<ExternType*>;
+
+ auto kind() const -> ExternKind;
+
+ auto func() -> FuncType*;
+ auto global() -> GlobalType*;
+ auto table() -> TableType*;
+ auto memory() -> MemoryType*;
+
+ auto func() const -> const FuncType*;
+ auto global() const -> const GlobalType*;
+ auto table() const -> const TableType*;
+ auto memory() const -> const MemoryType*;
+};
+
+
+// Function Types
+
+enum class arrow { ARROW };
+
+class FuncType : public ExternType {
+public:
+ FuncType() = delete;
+ ~FuncType();
+
+ static auto make(
+ vec<ValType*>&& params = vec<ValType*>::make(),
+ vec<ValType*>&& results = vec<ValType*>::make()
+ ) -> own<FuncType*>;
+
+ auto copy() const -> own<FuncType*>;
+
+ auto params() const -> const vec<ValType*>&;
+ auto results() const -> const vec<ValType*>&;
+};
+
+
+// Global Types
+
+class GlobalType : public ExternType {
+public:
+ GlobalType() = delete;
+ ~GlobalType();
+
+ static auto make(own<ValType*>&&, Mutability) -> own<GlobalType*>;
+ auto copy() const -> own<GlobalType*>;
+
+ auto content() const -> const ValType*;
+ auto mutability() const -> Mutability;
+};
+
+
+// Table Types
+
+class TableType : public ExternType {
+public:
+ TableType() = delete;
+ ~TableType();
+
+ static auto make(own<ValType*>&&, Limits) -> own<TableType*>;
+ auto copy() const -> own<TableType*>;
+
+ auto element() const -> const ValType*;
+ auto limits() const -> const Limits&;
+};
+
+
+// Memory Types
+
+class MemoryType : public ExternType {
+public:
+ MemoryType() = delete;
+ ~MemoryType();
+
+ static auto make(Limits) -> own<MemoryType*>;
+ auto copy() const -> own<MemoryType*>;
+
+ auto limits() const -> const Limits&;
+};
+
+
+// Import Types
+
+using Name = vec<byte_t>;
+
+class ImportType {
+public:
+ ImportType() = delete;
+ ~ImportType();
+ void operator delete(void*);
+
+ static auto make(Name&& module, Name&& name, own<ExternType*>&&) ->
+ own<ImportType*>;
+ auto copy() const -> own<ImportType*>;
+
+ auto module() const -> const Name&;
+ auto name() const -> const Name&;
+ auto type() const -> const ExternType*;
+};
+
+
+// Export Types
+
+class ExportType {
+public:
+ ExportType() = delete;
+ ~ExportType();
+ void operator delete(void*);
+
+ static auto make(Name&&, own<ExternType*>&&) -> own<ExportType*>;
+ auto copy() const -> own<ExportType*>;
+
+ auto name() const -> const Name&;
+ auto type() const -> const ExternType*;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Runtime Objects
+
+// References
+
+class Ref {
+public:
+ Ref() = delete;
+ ~Ref();
+ void operator delete(void*);
+
+ auto copy() const -> own<Ref*>;
+
+ auto get_host_info() const -> void*;
+ void set_host_info(void* info, void (*finalizer)(void*) = nullptr);
+};
+
+
+// Values
+
+class Val {
+ ValKind kind_;
+ union impl {
+ int32_t i32;
+ int64_t i64;
+ float32_t f32;
+ float64_t f64;
+ Ref* ref;
+ } impl_;
+
+ Val(ValKind kind, impl impl) : kind_(kind), impl_(impl) {}
+
+public:
+ Val() : kind_(ANYREF) { impl_.ref = nullptr; }
+ Val(int32_t i) : kind_(I32) { impl_.i32 = i; }
+ Val(int64_t i) : kind_(I64) { impl_.i64 = i; }
+ Val(float32_t z) : kind_(F32) { impl_.f32 = z; }
+ Val(float64_t z) : kind_(F64) { impl_.f64 = z; }
+ Val(own<Ref*>&& r) : kind_(ANYREF) { impl_.ref = r.release(); }
+
+ Val(Val&& that) : kind_(that.kind_), impl_(that.impl_) {
+ if (is_ref()) that.impl_.ref = nullptr;
+ }
+
+ ~Val() {
+ reset();
+ }
+
+ auto is_num() const -> bool { return wasm::is_num(kind_); }
+ auto is_ref() const -> bool { return wasm::is_ref(kind_); }
+
+ static auto i32(int32_t x) -> Val { return Val(x); }
+ static auto i64(int64_t x) -> Val { return Val(x); }
+ static auto f32(float32_t x) -> Val { return Val(x); }
+ static auto f64(float64_t x) -> Val { return Val(x); }
+ static auto ref(own<Ref*>&& x) -> Val { return Val(std::move(x)); }
+ template<class T> inline static auto make(T x) -> Val;
+ template<class T> inline static auto make(own<T>&& x) -> Val;
+
+ void reset() {
+ if (is_ref() && impl_.ref) {
+ delete impl_.ref;
+ impl_.ref = nullptr;
+ }
+ }
+
+ void reset(Val& that) {
+ reset();
+ kind_ = that.kind_;
+ impl_ = that.impl_;
+ if (is_ref()) that.impl_.ref = nullptr;
+ }
+
+ auto operator=(Val&& that) -> Val& {
+ reset(that);
+ return *this;
+ }
+
+ auto kind() const -> ValKind { return kind_; }
+ auto i32() const -> int32_t { assert(kind_ == I32); return impl_.i32; }
+ auto i64() const -> int64_t { assert(kind_ == I64); return impl_.i64; }
+ auto f32() const -> float32_t { assert(kind_ == F32); return impl_.f32; }
+ auto f64() const -> float64_t { assert(kind_ == F64); return impl_.f64; }
+ auto ref() const -> Ref* { assert(is_ref()); return impl_.ref; }
+ template<class T> inline auto get() const -> T;
+
+ auto release_ref() -> own<Ref*> {
+ assert(is_ref());
+ auto ref = impl_.ref;
+ ref = nullptr;
+ return own<Ref*>(ref);
+ }
+
+ auto copy() const -> Val {
+ if (is_ref() && impl_.ref != nullptr) {
+ impl impl;
+ impl.ref = impl_.ref->copy().release();
+ return Val(kind_, impl);
+ } else {
+ return Val(kind_, impl_);
+ }
+ }
+};
+
+
+template<> inline auto Val::make<int32_t>(int32_t x) -> Val { return Val(x); }
+template<> inline auto Val::make<int64_t>(int64_t x) -> Val { return Val(x); }
+template<> inline auto Val::make<float32_t>(float32_t x) -> Val { return Val(x); }
+template<> inline auto Val::make<float64_t>(float64_t x) -> Val { return Val(x); }
+template<> inline auto Val::make<Ref*>(own<Ref*>&& x) -> Val {
+ return Val(std::move(x));
+}
+
+template<> inline auto Val::make<uint32_t>(uint32_t x) -> Val {
+ return Val(static_cast<int32_t>(x));
+}
+template<> inline auto Val::make<uint64_t>(uint64_t x) -> Val {
+ return Val(static_cast<int64_t>(x));
+}
+
+template<> inline auto Val::get<int32_t>() const -> int32_t { return i32(); }
+template<> inline auto Val::get<int64_t>() const -> int64_t { return i64(); }
+template<> inline auto Val::get<float32_t>() const -> float32_t { return f32(); }
+template<> inline auto Val::get<float64_t>() const -> float64_t { return f64(); }
+template<> inline auto Val::get<Ref*>() const -> Ref* { return ref(); }
+
+template<> inline auto Val::get<uint32_t>() const -> uint32_t {
+ return static_cast<uint32_t>(i32());
+}
+template<> inline auto Val::get<uint64_t>() const -> uint64_t {
+ return static_cast<uint64_t>(i64());
+}
+
+
+// Traps
+
+using Message = vec<byte_t>; // null terminated
+
+class Trap : public Ref {
+public:
+ Trap() = delete;
+ ~Trap();
+
+ static auto make(Store*, const Message& msg) -> own<Trap*>;
+ auto copy() const -> own<Trap*>;
+
+ auto message() const -> Message;
+};
+
+
+// Shared objects
+
+template<class T>
+class Shared {
+public:
+ Shared() = delete;
+ ~Shared();
+ void operator delete(void*);
+};
+
+
+// Modules
+
+class Module : public Ref {
+public:
+ Module() = delete;
+ ~Module();
+
+ static auto validate(Store*, const vec<byte_t>& binary) -> bool;
+ static auto make(Store*, const vec<byte_t>& binary) -> own<Module*>;
+ auto copy() const -> own<Module*>;
+
+ auto imports() const -> vec<ImportType*>;
+ auto exports() const -> vec<ExportType*>;
+
+ auto share() const -> own<Shared<Module>*>;
+ static auto obtain(Store*, const Shared<Module>*) -> own<Module*>;
+
+ auto serialize() const -> vec<byte_t>;
+ static auto deserialize(Store*, const vec<byte_t>&) -> own<Module*>;
+};
+
+
+// Foreign Objects
+
+class Foreign : public Ref {
+public:
+ Foreign() = delete;
+ ~Foreign();
+
+ static auto make(Store*) -> own<Foreign*>;
+ auto copy() const -> own<Foreign*>;
+};
+
+
+// Externals
+
+class Func;
+class Global;
+class Table;
+class Memory;
+
+class Extern : public Ref {
+public:
+ Extern() = delete;
+ ~Extern();
+
+ auto copy() const -> own<Extern*>;
+
+ auto kind() const -> ExternKind;
+ auto type() const -> own<ExternType*>;
+
+ auto func() -> Func*;
+ auto global() -> Global*;
+ auto table() -> Table*;
+ auto memory() -> Memory*;
+
+ auto func() const -> const Func*;
+ auto global() const -> const Global*;
+ auto table() const -> const Table*;
+ auto memory() const -> const Memory*;
+};
+
+
+// Function Instances
+
+class Func : public Extern {
+public:
+ Func() = delete;
+ ~Func();
+
+ using callback = auto (*)(const Val[], Val[]) -> own<Trap*>;
+ using callback_with_env = auto (*)(void*, const Val[], Val[]) -> own<Trap*>;
+
+ static auto make(Store*, const FuncType*, callback) -> own<Func*>;
+ static auto make(Store*, const FuncType*, callback_with_env,
+ void*, void (*finalizer)(void*) = nullptr) -> own<Func*>;
+ auto copy() const -> own<Func*>;
+
+ auto type() const -> own<FuncType*>;
+ auto param_arity() const -> size_t;
+ auto result_arity() const -> size_t;
+
+ auto call(const Val[] = nullptr, Val[] = nullptr) const -> own<Trap*>;
+};
+
+
+// Global Instances
+
+class Global : public Extern {
+public:
+ Global() = delete;
+ ~Global();
+
+ static auto make(Store*, const GlobalType*, const Val&) -> own<Global*>;
+ auto copy() const -> own<Global*>;
+
+ auto type() const -> own<GlobalType*>;
+ auto get() const -> Val;
+ void set(const Val&);
+};
+
+
+// Table Instances
+
+class Table : public Extern {
+public:
+ Table() = delete;
+ ~Table();
+
+ using size_t = uint32_t;
+
+ static auto make(
+ Store*, const TableType*, const Ref* init = nullptr) -> own<Table*>;
+ auto copy() const -> own<Table*>;
+
+ auto type() const -> own<TableType*>;
+ auto get(size_t index) const -> own<Ref*>;
+ auto set(size_t index, const Ref*) -> bool;
+ auto size() const -> size_t;
+ auto grow(size_t delta, const Ref* init = nullptr) -> bool;
+};
+
+
+// Memory Instances
+
+class Memory : public Extern {
+public:
+ Memory() = delete;
+ ~Memory();
+
+ static auto make(Store*, const MemoryType*) -> own<Memory*>;
+ auto copy() const -> own<Memory*>;
+
+ using pages_t = uint32_t;
+
+ static const size_t page_size = 0x10000;
+
+ auto type() const -> own<MemoryType*>;
+ auto data() const -> byte_t*;
+ auto data_size() const -> size_t;
+ auto size() const -> pages_t;
+ auto grow(pages_t delta) -> bool;
+};
+
+
+// Module Instances
+
+class Instance : public Ref {
+public:
+ Instance() = delete;
+ ~Instance();
+
+ static auto make(
+ Store*, const Module*, const Extern* const[]) -> own<Instance*>;
+ auto copy() const -> own<Instance*>;
+
+ auto exports() const -> vec<Extern*>;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespave wasm
+
+#endif // #ifdef __WASM_HH