Commit f80bfeaf authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[wasm] Draft version of C/C++ Wasm API

Imported from https://github.com/WebAssembly/wasm-c-api/ and
updated to work inside V8.
Tests will be added in an upcoming CL.

This is experimental; it is not yet recommended to rely on it.

Change-Id: I05914f4b63298bf7c848c4d4c8811f0f6eb882e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1516478
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60910}
parent bfc8afdb
......@@ -3664,6 +3664,27 @@ if (v8_monolithic) {
}
}
v8_static_library("wee8") {
deps = [
":v8_base",
":v8_libbase",
":v8_libplatform",
":v8_libsampler",
":v8_maybe_snapshot",
"//build/win:default_exe_manifest",
]
# TODO: v8dll-main.cc equivalent for shared library builds
configs = [ ":internal_config" ]
sources = [
"src/wasm/c-api.cc",
"third_party/wasm-c-api/wasm.h",
"third_party/wasm-c-api/wasm.hh",
]
}
###############################################################################
# Executables
#
......
......@@ -20,11 +20,13 @@ are:
This code is copyrighted by Sun Microsystems Inc. and released
under a 3-clause BSD license.
- Valgrind client API header, located at third_party/valgrind/valgrind.h
This is release under the BSD license.
- Valgrind client API header, located at src/third_party/valgrind/valgrind.h
This is released under the BSD license.
- antlr4 parser generator Cpp library located in third_party/antlr4
This is release under the BSD license.
- The Wasm C/C++ API headers, located at third_party/wasm-api/wasm.{h,hh}
This is released under the Apache license. The API's upstream prototype
implementation also formed the basis of V8's implementation in
src/wasm/c-api.cc.
These libraries have their own licenses; we recommend you read them,
as their terms may differ from the terms below.
......
specific_include_rules = {
"c-api\.cc": [
"+include/libplatform/libplatform.h",
"+third_party/wasm-api/wasm.h",
"+third_party/wasm-api/wasm.hh",
],
}
This source diff could not be displayed because it is too large. You can view the blob instead.
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.
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.
This is only the contents of the "include/" directory of the upstream
repository.
// 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
// 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment