Enable WASI feature, enhance security and add SGX sample (#142)

Change emcc to clang
Refine interpreter to improve perforamnce
This commit is contained in:
Weining 2019-11-20 21:16:36 +08:00 committed by wenyongh
parent 29c7c743e9
commit 27f246b5f3
159 changed files with 9543 additions and 3789 deletions

View File

@ -1,14 +1,23 @@
# Contributor Covenant Code of Conduct +++
version = "1.4"
aliases = ["/version/1/4"]
+++
*Note*: this Code of Conduct pertains to individuals' behavior. Please also see the [Organizational Code of Conduct][OCoC]. # Contributor Covenant Code of Conduct
## Our Pledge ## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards ## Our Standards
Examples of behavior that contributes to creating a positive environment include: Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language * Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences * Being respectful of differing viewpoints and experiences
@ -18,32 +27,55 @@ Examples of behavior that contributes to creating a positive environment include
Examples of unacceptable behavior by participants include: Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances * The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks * Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment * Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission * Publishing others' private information, such as a physical or electronic
* Other conduct which could reasonably be considered inappropriate in a professional setting address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities ## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope ## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.
## Enforcement ## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Bytecode Alliance CoC team at [report@bytecodealliance.org](mailto:report@bytecodealliance.org). The CoC team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The CoC team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at otc.community.care@intel.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the Bytecode Alliance's leadership. Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution ## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[OCoC]: ORG_CODE_OF_CONDUCT.md
[homepage]: https://www.contributor-covenant.org [homepage]: https://www.contributor-covenant.org
[version]: https://www.contributor-covenant.org/version/1/4/
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View File

@ -36,4 +36,5 @@ We use GitHub issues to track public bugs. Report a bug by [open a new issue](ht
Code of Conduct Code of Conduct
=============== ===============
WAMR is a [Bytecode Alliance](https://bytecodealliance.org/) project, and follows the Bytecode Alliance's [Code of Conduct](CODE_OF_CONDUCT.md) and [Organizational Code of Conduct](ORG_CODE_OF_CONDUCT.md). This project is governed by the [Contributor Covenant](CODE_OF_CONDUCT.md).
All contributors and participants agree to abide by its terms.

View File

@ -1,139 +0,0 @@
# Bytecode Alliance Organizational Code of Conduct (OCoC)
*Note*: this Code of Conduct pertains to organizations' behavior. Please also see the [Individual Code of Conduct](CODE_OF_CONDUCT.md).
## Preamble
The Bytecode Alliance (BA) welcomes involvement from organizations,
including commercial organizations. This document is an
*organizational* code of conduct, intended particularly to provide
guidance to commercial organizations. It is distinct from the
[Individual Code of Conduct (ICoC)](CODE_OF_CONDUCT.md), and does not
replace the ICoC. This OCoC applies to any group of people acting in
concert as a BA member or as a participant in BA activities, whether
or not that group is formally incorporated in some jurisdiction.
The code of conduct described below is not a set of rigid rules, and
we did not write it to encompass every conceivable scenario that might
arise. For example, it is theoretically possible there would be times
when asserting patents is in the best interest of the BA community as
a whole. In such instances, consult with the BA, strive for
consensus, and interpret these rules with an intent that is generous
to the community the BA serves.
While we may revise these guidelines from time to time based on
real-world experience, overall they are based on a simple principle:
*Bytecode Alliance members should observe the distinction between
public community functions and private functions — especially
commercial ones — and should ensure that the latter support, or at
least do not harm, the former.*
## Guidelines
* **Do not cause confusion about Wasm standards or interoperability.**
Having an interoperable WebAssembly core is a high priority for
the BA, and members should strive to preserve that core. It is fine
to develop additional non-standard features or APIs, but they
should always be clearly distinguished from the core interoperable
Wasm.
Treat the WebAssembly name and any BA-associated names with
respect, and follow BA trademark and branding guidelines. If you
distribute a customized version of software originally produced by
the BA, or if you build a product or service using BA-derived
software, use names that clearly distinguish your work from the
original. (You should still provide proper attribution to the
original, of course, wherever such attribution would normally be
given.)
Further, do not use the WebAssembly name or BA-associated names in
other public namespaces in ways that could cause confusion, e.g.,
in company names, names of commercial service offerings, domain
names, publicly-visible social media accounts or online service
accounts, etc. It may sometimes be reasonable, however, to
register such a name in a new namespace and then immediately donate
control of that account to the BA, because that would help the project
maintain its identity.
* **Do not restrict contributors.** If your company requires
employees or contractors to sign non-compete agreements, those
agreements must not prevent people from participating in the BA or
contributing to related projects.
This does not mean that all non-compete agreements are incompatible
with this code of conduct. For example, a company may restrict an
employee's ability to solicit the company's customers. However, an
agreement must not block any form of technical or social
participation in BA activities, including but not limited to the
implementation of particular features.
The accumulation of experience and expertise in individual persons,
who are ultimately free to direct their energy and attention as
they decide, is one of the most important drivers of progress in
open source projects. A company that limits this freedom may hinder
the success of the BA's efforts.
* **Do not use patents as offensive weapons.** If any BA participant
prevents the adoption or development of BA technologies by
asserting its patents, that undermines the purpose of the
coalition. The collaboration fostered by the BA cannot include
members who act to undermine its work.
* **Practice responsible disclosure** for security vulnerabilities.
Use designated, non-public reporting channels to disclose technical
vulnerabilities, and give the project a reasonable period to
respond, remediate, and patch.
Vulnerability reporters may patch their company's own offerings, as
long as that patching does not significantly delay the reporting of
the vulnerability. Vulnerability information should never be used
for unilateral commercial advantage. Vendors may legitimately
compete on the speed and reliability with which they deploy
security fixes, but withholding vulnerability information damages
everyone in the long run by risking harm to the BA project's
reputation and to the security of all users.
* **Respect the letter and spirit of open source practice.** While
there is not space to list here all possible aspects of standard
open source practice, some examples will help show what we mean:
* Abide by all applicable open source license terms. Do not engage
in copyright violation or misattribution of any kind.
* Do not claim others' ideas or designs as your own.
* When others engage in publicly visible work (e.g., an upcoming
demo that is coordinated in a public issue tracker), do not
unilaterally announce early releases or early demonstrations of
that work ahead of their schedule in order to secure private
advantage (such as marketplace advantage) for yourself.
The BA reserves the right to determine what constitutes good open
source practices and to take action as it deems appropriate to
encourage, and if necessary enforce, such practices.
## Enforcement
Instances of organizational behavior in violation of the OCoC may
be reported by contacting the Bytecode Alliance CoC team at
[report@bytecodealliance.org](mailto:report@bytecodealliance.org). The
CoC team will review and investigate all complaints, and will respond
in a way that it deems appropriate to the circumstances. The CoC team
is obligated to maintain confidentiality with regard to the reporter of
an incident. Further details of specific enforcement policies may be
posted separately.
When the BA deems an organization in violation of this OCoC, the BA
will, at its sole discretion, determine what action to take. The BA
will decide what type, degree, and duration of corrective action is
needed, if any, before a violating organization can be considered for
membership (if it was not already a member) or can have its membership
reinstated (if it was a member and the BA canceled its membership due
to the violation).
In practice, the BA's first approach will be to start a conversation,
with punitive enforcement used only as a last resort. Violations
often turn out to be unintentional and swiftly correctable with all
parties acting in good faith.

View File

@ -1,10 +1,5 @@
WebAssembly Micro Runtime WebAssembly Micro Runtime
========================= =========================
**A [Bytecode Alliance][BA] project**
[BA]: https://bytecodealliance.org/
WebAssembly Micro Runtime (WAMR) is a standalone WebAssembly (WASM) runtime with small footprint. It includes a few parts as below: WebAssembly Micro Runtime (WAMR) is a standalone WebAssembly (WASM) runtime with small footprint. It includes a few parts as below:
- A WebAssembly VM core (namely iwasm) - A WebAssembly VM core (namely iwasm)
- The supporting API's for the WASM applications - The supporting API's for the WASM applications
@ -14,8 +9,8 @@ WebAssembly Micro Runtime (WAMR) is a standalone WebAssembly (WASM) runtime with
Current Features of WAMR Current Features of WAMR
========================= =========================
- WASM interpreter (AOT is planned) - WASM interpreter (AOT is planned)
- Supports for a subset of Libc. - Supports for a subset of Libc API.
- Supports "SIDE_MODULE=1" EMCC compilation option - Supports for [WASI API](https://github.com/WebAssembly/WASI)
- Provides embedding C API - Provides embedding C API
- Provides a mechanism for exporting native API's to WASM applications - Provides a mechanism for exporting native API's to WASM applications
- Supports the programming of firmware apps in a large range of languages (C/C++/Java/Rust/Go/TypeScript etc.) - Supports the programming of firmware apps in a large range of languages (C/C++/Java/Rust/Go/TypeScript etc.)
@ -71,7 +66,7 @@ WAMR application programming library
WAMR defined event driven programming model: WAMR defined event driven programming model:
- Single thread per WASM app instance - Single thread per WASM app instance
- App must implement system callbacks: on_init, on_destroy - App must implement system callbacks: on_init, on_destrory
In general there are a few API classes for the WASM application programming: In general there are a few API classes for the WASM application programming:
@ -117,7 +112,7 @@ See the [major features releasing history and contributor names](./doc/release_a
Roadmap Roadmap
======= =======
See the [roadmap](./doc/roadmap.md) to understand what major features are planned or under development. See the [roadmap](./doc/roadmap.md) to understand what major features are planed or under development.
Please submit issues for any new feature request, or your plan for contributing new features. Please submit issues for any new feature request, or your plan for contributing new features.

View File

@ -1,29 +0,0 @@
# Security Policy
Building secure foundations for software development is at the core of what we do in the Bytecode Alliance. Contributions of external security researchers are a vital part of that.
## Scope
If you believe you've found a security issue in any website, service, or software owned or operated by the Bytecode Alliance, we encourage you to notify us.
## How to Submit a Report
To submit a vulnerability report to the Bytecode Alliance, please contact us at [security@bytecodealliance.org](mailto:security@bytecodealliance.org). Your submission will be reviewed and validated by a member of our security team.
## Safe Harbor
The Bytecode Alliance supports safe harbor for security researchers who:
* Make a good faith effort to avoid privacy violations, destruction of data, and interruption or degradation of our services.
* Only interact with accounts you own or with explicit permission of the account holder. If you do encounter Personally Identifiable Information (PII) contact us immediately, do not proceed with access, and immediately purge any local information.
* Provide us with a reasonable amount of time to resolve vulnerabilities prior to any disclosure to the public or a third-party.
We will consider activities conducted consistent with this policy to constitute "authorized" conduct and will not pursue civil action or initiate a complaint to law enforcement. We will help to the extent we can if legal action is initiated by a third party against you.
Please submit a report to us before engaging in conduct that may be inconsistent with or unaddressed by this policy.
## Preferences
* Please provide detailed reports with reproducible steps and a clearly defined impact.
* Submit one vulnerability per report.
* Social engineering (e.g. phishing, vishing, smishing) is prohibited.

View File

@ -24,10 +24,6 @@ extern "C" {
#define app_manager_printf printk #define app_manager_printf printk
#endif #endif
#define ID_HOST -3
#define ID_APP_MGR -2
#define ID_NONE (uint32)-1
#define SEND_ERR_RESPONSE(mid, err_msg) do { \ #define SEND_ERR_RESPONSE(mid, err_msg) do { \
app_manager_printf("%s\n", err_msg); \ app_manager_printf("%s\n", err_msg); \
send_error_response_to_host(mid, INTERNAL_SERVER_ERROR_5_00, err_msg); \ send_error_response_to_host(mid, INTERNAL_SERVER_ERROR_5_00, err_msg); \

View File

@ -121,7 +121,8 @@ module_data_list_lookup_id(unsigned int module_id)
module_data * module_data *
app_manager_get_module_data(uint32 module_type, void *module_inst) app_manager_get_module_data(uint32 module_type, void *module_inst)
{ {
if (g_module_interfaces[module_type] if (module_type < Module_Max
&& g_module_interfaces[module_type]
&& g_module_interfaces[module_type]->module_get_module_data) && g_module_interfaces[module_type]->module_get_module_data)
return g_module_interfaces[module_type]->module_get_module_data(module_inst); return g_module_interfaces[module_type]->module_get_module_data(module_inst);
return NULL; return NULL;
@ -130,24 +131,28 @@ app_manager_get_module_data(uint32 module_type, void *module_inst)
void* void*
app_manager_get_module_queue(uint32 module_type, void *module_inst) app_manager_get_module_queue(uint32 module_type, void *module_inst)
{ {
return app_manager_get_module_data(module_type, module_inst)->queue; module_data *m_data = app_manager_get_module_data(module_type, module_inst);
return m_data ? m_data->queue : NULL;
} }
const char* const char*
app_manager_get_module_name(uint32 module_type, void *module_inst) app_manager_get_module_name(uint32 module_type, void *module_inst)
{ {
return app_manager_get_module_data(module_type, module_inst)->module_name; module_data *m_data = app_manager_get_module_data(module_type, module_inst);
return m_data ? m_data->module_name : NULL;
} }
unsigned int app_manager_get_module_id(uint32 module_type, void *module_inst) unsigned int app_manager_get_module_id(uint32 module_type, void *module_inst)
{ {
return app_manager_get_module_data(module_type, module_inst)->id; module_data *m_data = app_manager_get_module_data(module_type, module_inst);
return m_data ? m_data->id : ID_NONE;
} }
void* void*
app_manager_get_module_heap(uint32 module_type, void *module_inst) app_manager_get_module_heap(uint32 module_type, void *module_inst)
{ {
return app_manager_get_module_data(module_type, module_inst)->heap; module_data *m_data = app_manager_get_module_data(module_type, module_inst);
return m_data ? m_data->heap : NULL;
} }
module_data* module_data*
@ -170,7 +175,8 @@ void app_manager_del_module_data(module_data *m_data)
bool app_manager_is_interrupting_module(uint32 module_type, void *module_inst) bool app_manager_is_interrupting_module(uint32 module_type, void *module_inst)
{ {
return app_manager_get_module_data(module_type, module_inst)->wd_timer.is_interrupting; module_data *m_data = app_manager_get_module_data(module_type, module_inst);
return m_data ? m_data->wd_timer.is_interrupting : false;
} }
extern void destroy_module_timer_ctx(unsigned int module_id); extern void destroy_module_timer_ctx(unsigned int module_id);

View File

@ -17,12 +17,20 @@
#include "runtime_lib.h" #include "runtime_lib.h"
/* Wasm app 4 magic bytes */ /* Wasm app 4 magic bytes */
static unsigned char wasm_app_magics[] = { (unsigned char) 0x00, static unsigned char wasm_app_magics[] = {
(unsigned char) 0x61, (unsigned char) 0x73, (unsigned char) 0x6d }; (unsigned char) 0x00,
(unsigned char) 0x61,
(unsigned char) 0x73,
(unsigned char) 0x6d
};
/* Wasm app 4 version bytes */ /* Wasm app 4 version bytes */
static unsigned char wasm_app_version[] = { (unsigned char) 0x01, static unsigned char wasm_app_version[] = {
(unsigned char) 0x00, (unsigned char) 0x00, (unsigned char) 0x00 }; (unsigned char) 0x01,
(unsigned char) 0x00,
(unsigned char) 0x00,
(unsigned char) 0x00
};
/* Wasm App Install Request Receiving Phase */ /* Wasm App Install Request Receiving Phase */
typedef enum wasm_app_install_req_recv_phase_t { typedef enum wasm_app_install_req_recv_phase_t {
@ -84,14 +92,18 @@ int g_msg_type[Max_Msg_Callback] = { 0 };
message_type_handler_t g_msg_callbacks[Max_Msg_Callback] = { 0 }; message_type_handler_t g_msg_callbacks[Max_Msg_Callback] = { 0 };
#define Max_Cleanup_Callback 10 #define Max_Cleanup_Callback 10
static resource_cleanup_handler_t g_cleanup_callbacks[Max_Cleanup_Callback] = { static resource_cleanup_handler_t
0 }; g_cleanup_callbacks[Max_Cleanup_Callback] = { 0 };
module_interface wasm_app_module_interface = { wasm_app_module_init, module_interface wasm_app_module_interface = {
wasm_app_module_install, wasm_app_module_uninstall, wasm_app_module_init,
wasm_app_module_watchdog_kill, wasm_app_module_handle_host_url, wasm_app_module_install,
wasm_app_module_uninstall,
wasm_app_module_watchdog_kill,
wasm_app_module_handle_host_url,
wasm_app_module_get_module_data, wasm_app_module_get_module_data,
wasm_app_module_on_install_request_byte_arrive }; wasm_app_module_on_install_request_byte_arrive
};
static unsigned align_uint(unsigned v, unsigned b) static unsigned align_uint(unsigned v, unsigned b)
{ {
@ -99,6 +111,19 @@ static unsigned align_uint(unsigned v, unsigned b)
return (v + m) & ~m; return (v + m) & ~m;
} }
static wasm_function_inst_t
app_manager_lookup_function(const wasm_module_inst_t module_inst,
const char *name, const char *signature)
{
wasm_function_inst_t func;
func = wasm_runtime_lookup_function(module_inst, name, signature);
if (!func && name[0] == '_')
func = wasm_runtime_lookup_function(module_inst, name + 1, signature);
return func;
}
static void app_instance_queue_callback(void *queue_msg, void *arg) static void app_instance_queue_callback(void *queue_msg, void *arg)
{ {
uint32 argv[2]; uint32 argv[2];
@ -108,6 +133,9 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
module_data *m_data = app_manager_get_module_data(Module_WASM_App, inst); module_data *m_data = app_manager_get_module_data(Module_WASM_App, inst);
int message_type = bh_message_type(queue_msg); int message_type = bh_message_type(queue_msg);
bh_assert(m_data);
if (message_type < BASE_EVENT_MAX) {
switch (message_type) { switch (message_type) {
case RESTFUL_REQUEST: { case RESTFUL_REQUEST: {
request_t *request = (request_t *)bh_message_payload(queue_msg); request_t *request = (request_t *)bh_message_payload(queue_msg);
@ -116,9 +144,12 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
int32 buffer_offset; int32 buffer_offset;
app_manager_printf("App %s got request, url %s, action %d\n", app_manager_printf("App %s got request, url %s, action %d\n",
m_data->module_name, request->url, request->action); m_data->module_name,
request->url,
request->action);
func_onRequest = wasm_runtime_lookup_function(inst, "_on_request", func_onRequest = app_manager_lookup_function(inst,
"_on_request",
"(i32i32)"); "(i32i32)");
if (!func_onRequest) { if (!func_onRequest) {
app_manager_printf("Cannot find function onRequest\n"); app_manager_printf("Cannot find function onRequest\n");
@ -156,6 +187,7 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
break; break;
} }
case RESTFUL_RESPONSE: { case RESTFUL_RESPONSE: {
wasm_function_inst_t func_onResponse;
response_t *response = (response_t *) bh_message_payload(queue_msg); response_t *response = (response_t *) bh_message_payload(queue_msg);
int size; int size;
char *buffer; char *buffer;
@ -164,8 +196,8 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
app_manager_printf("App %s got response_t,status %d\n", app_manager_printf("App %s got response_t,status %d\n",
m_data->module_name, response->status); m_data->module_name, response->status);
wasm_function_inst_t func_onResponse = wasm_runtime_lookup_function( func_onResponse =
inst, "_on_response", "(i32i32)"); app_manager_lookup_function(inst, "_on_response", "(i32i32)");
if (!func_onResponse) { if (!func_onResponse) {
app_manager_printf("Cannot find function on_response\n"); app_manager_printf("Cannot find function on_response\n");
break; break;
@ -201,30 +233,6 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
app_manager_printf("Wasm app process response success.\n"); app_manager_printf("Wasm app process response success.\n");
break; break;
} }
case TIMER_EVENT_WASM: {
if (bh_message_payload(queue_msg)) {
/* Call Timer.callOnTimer() method */
func_onTimer = wasm_runtime_lookup_function(inst,
"_on_timer_callback", "(i32)");
if (!func_onTimer) {
app_manager_printf("Cannot find function _on_timer_callback\n");
break;
}
unsigned int timer_id = (unsigned int)(uintptr_t)
bh_message_payload(queue_msg);
argv[0] = timer_id;
if (!wasm_runtime_call_wasm(inst, NULL, func_onTimer, 1, argv)) {
app_manager_printf("Got exception running wasm code: %s\n",
wasm_runtime_get_exception(inst));
wasm_runtime_clear_exception(inst);
}
}
break;
}
default: { default: {
for (int i = 0; i < Max_Msg_Callback; i++) { for (int i = 0; i < Max_Msg_Callback; i++) {
if (g_msg_type[i] == message_type) { if (g_msg_type[i] == message_type) {
@ -234,6 +242,47 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
} }
app_manager_printf("Invalid message type of WASM app queue message.\n"); app_manager_printf("Invalid message type of WASM app queue message.\n");
break; break;
}
}
}
else {
switch (message_type) {
case TIMER_EVENT_WASM: {
unsigned int timer_id;
if (bh_message_payload(queue_msg)) {
/* Call Timer.callOnTimer() method */
func_onTimer =
app_manager_lookup_function(inst,
"_on_timer_callback",
"(i32)");
if (!func_onTimer) {
app_manager_printf("Cannot find function _on_timer_callback\n");
break;
}
timer_id =
(unsigned int)(uintptr_t)bh_message_payload(queue_msg);
argv[0] = timer_id;
if (!wasm_runtime_call_wasm(inst, NULL, func_onTimer, 1, argv)) {
app_manager_printf("Got exception running wasm code: %s\n",
wasm_runtime_get_exception(inst));
wasm_runtime_clear_exception(inst);
}
}
break;
}
default: {
for (int i = 0; i < Max_Msg_Callback; i++) {
if (g_msg_type[i] == message_type) {
g_msg_callbacks[i](m_data, queue_msg);
return;
}
}
app_manager_printf("Invalid message type of WASM app queue message.\n");
break;
}
} }
} }
} }
@ -256,7 +305,7 @@ wasm_app_routine(void *arg)
app_manager_printf("WASM app '%s' started\n", m_data->module_name); app_manager_printf("WASM app '%s' started\n", m_data->module_name);
/* Call app's onInit() method */ /* Call app's onInit() method */
func_onInit = wasm_runtime_lookup_function(inst, "_on_init", "()"); func_onInit = app_manager_lookup_function(inst, "_on_init", "()");
if (!func_onInit) { if (!func_onInit) {
app_manager_printf("Cannot find function on_init().\n"); app_manager_printf("Cannot find function on_init().\n");
goto fail1; goto fail1;
@ -278,7 +327,7 @@ wasm_app_routine(void *arg)
fail2: fail2:
/* Call WASM app onDestroy() method if there is */ /* Call WASM app onDestroy() method if there is */
func_onDestroy = wasm_runtime_lookup_function(inst, "_on_destroy", "()"); func_onDestroy = app_manager_lookup_function(inst, "_on_destroy", "()");
if (func_onDestroy) if (func_onDestroy)
wasm_runtime_call_wasm(inst, NULL, func_onDestroy, 0, NULL); wasm_runtime_call_wasm(inst, NULL, func_onDestroy, 0, NULL);
@ -341,8 +390,8 @@ static bool wasm_app_module_init(void)
static bool wasm_app_module_install(request_t * msg) static bool wasm_app_module_install(request_t * msg)
{ {
unsigned int m_data_size, wasm_app_aot_file_len, heap_size, timeout, timers, unsigned int m_data_size, wasm_app_aot_file_len, heap_size;
err_size; unsigned int timeout, timers, err_size;
char *properties; char *properties;
int properties_offset, i; int properties_offset, i;
uint8 *wasm_app_aot_file; uint8 *wasm_app_aot_file;
@ -352,11 +401,13 @@ static bool wasm_app_module_install(request_t * msg)
module_data *m_data; module_data *m_data;
wasm_module_t module = NULL; wasm_module_t module = NULL;
wasm_module_inst_t inst = NULL; wasm_module_inst_t inst = NULL;
char m_name[APP_NAME_MAX_LEN] = { 0 }, timeout_str[MAX_INT_STR_LEN] = { 0 }, char m_name[APP_NAME_MAX_LEN] = { 0 };
heap_size_str[MAX_INT_STR_LEN] = { 0 }, char timeout_str[MAX_INT_STR_LEN] = { 0 };
timers_str[MAX_INT_STR_LEN] = { 0 }, err[256]; char heap_size_str[MAX_INT_STR_LEN] = { 0 };
char timers_str[MAX_INT_STR_LEN] = { 0 }, err[256];
/* Useless sections after load */ /* Useless sections after load */
uint8 sections1[] = { SECTION_TYPE_USER, uint8 sections1[] = {
SECTION_TYPE_USER,
SECTION_TYPE_TYPE, SECTION_TYPE_TYPE,
SECTION_TYPE_IMPORT, SECTION_TYPE_IMPORT,
SECTION_TYPE_FUNC, SECTION_TYPE_FUNC,
@ -367,7 +418,8 @@ static bool wasm_app_module_install(request_t * msg)
SECTION_TYPE_START, SECTION_TYPE_START,
SECTION_TYPE_ELEM, SECTION_TYPE_ELEM,
/*SECTION_TYPE_CODE,*/ /*SECTION_TYPE_CODE,*/
/*SECTION_TYPE_DATA*/}; /*SECTION_TYPE_DATA*/
};
/* Useless sections after instantiate */ /* Useless sections after instantiate */
uint8 sections2[] = { SECTION_TYPE_DATA }; uint8 sections2[] = { SECTION_TYPE_DATA };
@ -375,8 +427,7 @@ static bool wasm_app_module_install(request_t * msg)
/* Check payload */ /* Check payload */
if (!msg->payload || msg->payload_len == 0) { if (!msg->payload || msg->payload_len == 0) {
SEND_ERR_RESPONSE(msg->mid, SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: invalid wasm file.");
"Install WASM app failed: invalid wasm file.");
return false; return false;
} }
@ -390,14 +441,12 @@ static bool wasm_app_module_install(request_t * msg)
sizeof(m_name) - 1, '&'); sizeof(m_name) - 1, '&');
if (strlen(m_name) == 0) { if (strlen(m_name) == 0) {
SEND_ERR_RESPONSE(msg->mid, SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: invalid app name.");
"Install WASM app failed: invalid app name.");
return false; return false;
} }
if (app_manager_lookup_module_data(m_name)) { if (app_manager_lookup_module_data(m_name)) {
SEND_ERR_RESPONSE(msg->mid, SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: app already installed.");
"Install WASM app failed: app already installed.");
return false; return false;
} }
@ -427,7 +476,8 @@ static bool wasm_app_module_install(request_t * msg)
"Install WASM app failed: load wasm aot binary failed."); "Install WASM app failed: load wasm aot binary failed.");
return false; return false;
} }
} else if (package_type == Wasm_Module_Bytecode) { }
else if (package_type == Wasm_Module_Bytecode) {
wasm_app_file = (wasm_app_file_t *) msg->payload; wasm_app_file = (wasm_app_file_t *) msg->payload;
module = wasm_runtime_load_from_sections(wasm_app_file->sections, err, module = wasm_runtime_load_from_sections(wasm_app_file->sections, err,
err_size); err_size);
@ -459,7 +509,8 @@ static bool wasm_app_module_install(request_t * msg)
destroy_wasm_section_from_list(&wasm_app_file->sections, destroy_wasm_section_from_list(&wasm_app_file->sections,
sections2[i]); sections2[i]);
} else { }
else {
SEND_ERR_RESPONSE(msg->mid, SEND_ERR_RESPONSE(msg->mid,
"Install WASM app failed: invalid wasm package type."); "Install WASM app failed: invalid wasm package type.");
return false; return false;
@ -470,8 +521,7 @@ static bool wasm_app_module_install(request_t * msg)
m_data_size = align_uint(m_data_size, 4); m_data_size = align_uint(m_data_size, 4);
m_data = bh_malloc(m_data_size + sizeof(wasm_data)); m_data = bh_malloc(m_data_size + sizeof(wasm_data));
if (!m_data) { if (!m_data) {
SEND_ERR_RESPONSE(msg->mid, SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: allocate memory failed.");
"Install WASM app failed: allocate memory failed.");
goto fail; goto fail;
} }
memset(m_data, 0, m_data_size + sizeof(wasm_data)); memset(m_data, 0, m_data_size + sizeof(wasm_data));
@ -498,8 +548,7 @@ static bool wasm_app_module_install(request_t * msg)
/* Set module data - create queue */ /* Set module data - create queue */
m_data->queue = bh_queue_create(); m_data->queue = bh_queue_create();
if (!m_data->queue) { if (!m_data->queue) {
SEND_ERR_RESPONSE(msg->mid, SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: create app queue failed.");
"Install WASM app failed: create app queue failed.");
goto fail; goto fail;
} }
@ -539,7 +588,6 @@ static bool wasm_app_module_install(request_t * msg)
module_data_list_remove(m_data); module_data_list_remove(m_data);
SEND_ERR_RESPONSE(msg->mid, SEND_ERR_RESPONSE(msg->mid,
"Install WASM app failed: create app threadf failed."); "Install WASM app failed: create app threadf failed.");
goto fail; goto fail;
} }
@ -551,7 +599,8 @@ static bool wasm_app_module_install(request_t * msg)
return true; return true;
fail: if (m_data) fail:
if (m_data)
release_module(m_data); release_module(m_data);
wasm_runtime_deinstantiate(inst); wasm_runtime_deinstantiate(inst);
@ -583,8 +632,7 @@ static bool wasm_app_module_uninstall(request_t *msg)
sizeof(m_name) - 1, '&'); sizeof(m_name) - 1, '&');
if (strlen(m_name) == 0) { if (strlen(m_name) == 0) {
SEND_ERR_RESPONSE(msg->mid, SEND_ERR_RESPONSE(msg->mid, "Uninstall WASM app failed: invalid app name.");
"Uninstall WASM app failed: invalid app name.");
return false; return false;
} }
@ -595,8 +643,7 @@ static bool wasm_app_module_uninstall(request_t *msg)
} }
if (m_data->module_type != Module_WASM_App) { if (m_data->module_type != Module_WASM_App) {
SEND_ERR_RESPONSE(msg->mid, SEND_ERR_RESPONSE(msg->mid, "Uninstall WASM app failed: invalid module type.");
"Uninstall WASM app failed: invalid module type.");
return false; return false;
} }
@ -702,8 +749,9 @@ bool wasm_register_cleanup_callback(resource_cleanup_handler_t handler)
* 0: one valid byte arrived * 0: one valid byte arrived
* -1: fail to process the byte arrived, e.g. allocate memory fail * -1: fail to process the byte arrived, e.g. allocate memory fail
*/ */
static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch, static bool
int request_total_size, int *received_size) wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
int *received_size)
{ {
if (recv_ctx.phase == Phase_Req_Ver) { if (recv_ctx.phase == Phase_Req_Ver) {
recv_ctx.phase = Phase_Req_Ver; recv_ctx.phase = Phase_Req_Ver;
@ -719,30 +767,35 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
return false; return false;
recv_ctx.phase = Phase_Req_Action; recv_ctx.phase = Phase_Req_Action;
return true; return true;
} else if (recv_ctx.phase == Phase_Req_Action) { }
else if (recv_ctx.phase == Phase_Req_Action) {
recv_ctx.message.request_action = ch; recv_ctx.message.request_action = ch;
recv_ctx.phase = Phase_Req_Fmt; recv_ctx.phase = Phase_Req_Fmt;
recv_ctx.size_in_phase = 0; recv_ctx.size_in_phase = 0;
return true; return true;
} else if (recv_ctx.phase == Phase_Req_Fmt) { }
else if (recv_ctx.phase == Phase_Req_Fmt) {
RECV_INTEGER(recv_ctx.message.request_fmt, Phase_Req_Mid); RECV_INTEGER(recv_ctx.message.request_fmt, Phase_Req_Mid);
return true; return true;
} else if (recv_ctx.phase == Phase_Req_Mid) { }
else if (recv_ctx.phase == Phase_Req_Mid) {
RECV_INTEGER(recv_ctx.message.request_mid, Phase_Req_Sender); RECV_INTEGER(recv_ctx.message.request_mid, Phase_Req_Sender);
return true; return true;
} else if (recv_ctx.phase == Phase_Req_Sender) { }
else if (recv_ctx.phase == Phase_Req_Sender) {
RECV_INTEGER(recv_ctx.message.request_sender, Phase_Req_Url_Len); RECV_INTEGER(recv_ctx.message.request_sender, Phase_Req_Url_Len);
return true; return true;
} else if (recv_ctx.phase == Phase_Req_Url_Len) { }
else if (recv_ctx.phase == Phase_Req_Url_Len) {
unsigned char *p = (unsigned char *) &recv_ctx.message.request_url_len; unsigned char *p = (unsigned char *) &recv_ctx.message.request_url_len;
p[recv_ctx.size_in_phase++] = ch; p[recv_ctx.size_in_phase++] = ch;
if (recv_ctx.size_in_phase if (recv_ctx.size_in_phase ==
== sizeof(recv_ctx.message.request_url_len)) { sizeof(recv_ctx.message.request_url_len)) {
recv_ctx.message.request_url_len = ntohs( recv_ctx.message.request_url_len =
recv_ctx.message.request_url_len); ntohs(recv_ctx.message.request_url_len);
recv_ctx.message.request_url = bh_malloc( recv_ctx.message.request_url =
recv_ctx.message.request_url_len + 1); bh_malloc(recv_ctx.message.request_url_len + 1);
if (NULL == recv_ctx.message.request_url) if (NULL == recv_ctx.message.request_url)
goto fail; goto fail;
memset(recv_ctx.message.request_url, 0, memset(recv_ctx.message.request_url, 0,
@ -751,17 +804,20 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
recv_ctx.size_in_phase = 0; recv_ctx.size_in_phase = 0;
} }
return true; return true;
} else if (recv_ctx.phase == Phase_Req_Payload_Len) { }
else if (recv_ctx.phase == Phase_Req_Payload_Len) {
RECV_INTEGER(recv_ctx.message.wasm_app_size, Phase_Req_Url); RECV_INTEGER(recv_ctx.message.wasm_app_size, Phase_Req_Url);
return true; return true;
} else if (recv_ctx.phase == Phase_Req_Url) { }
else if (recv_ctx.phase == Phase_Req_Url) {
recv_ctx.message.request_url[recv_ctx.size_in_phase++] = ch; recv_ctx.message.request_url[recv_ctx.size_in_phase++] = ch;
if (recv_ctx.size_in_phase == recv_ctx.message.request_url_len) { if (recv_ctx.size_in_phase == recv_ctx.message.request_url_len) {
recv_ctx.phase = Phase_Wasm_Magic; recv_ctx.phase = Phase_Wasm_Magic;
recv_ctx.size_in_phase = 0; recv_ctx.size_in_phase = 0;
} }
return true; return true;
} else if (recv_ctx.phase == Phase_Wasm_Magic) { }
else if (recv_ctx.phase == Phase_Wasm_Magic) {
/* start to receive wasm app binary */ /* start to receive wasm app binary */
unsigned char *p = unsigned char *p =
(unsigned char *) &recv_ctx.message.wasm_app_binary.magic; (unsigned char *) &recv_ctx.message.wasm_app_binary.magic;
@ -771,14 +827,14 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
else else
goto fail; goto fail;
if (recv_ctx.size_in_phase if (recv_ctx.size_in_phase ==
== sizeof(recv_ctx.message.wasm_app_binary.magic)) { sizeof(recv_ctx.message.wasm_app_binary.magic)) {
recv_ctx.phase = Phase_Wasm_Version; recv_ctx.phase = Phase_Wasm_Version;
recv_ctx.size_in_phase = 0; recv_ctx.size_in_phase = 0;
} }
return true; return true;
} else if (recv_ctx.phase == Phase_Wasm_Version) { }
else if (recv_ctx.phase == Phase_Wasm_Version) {
unsigned char *p = unsigned char *p =
(unsigned char *) &recv_ctx.message.wasm_app_binary.version; (unsigned char *) &recv_ctx.message.wasm_app_binary.version;
@ -787,14 +843,14 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
else else
goto fail; goto fail;
if (recv_ctx.size_in_phase if (recv_ctx.size_in_phase ==
== sizeof(recv_ctx.message.wasm_app_binary.version)) { sizeof(recv_ctx.message.wasm_app_binary.version)) {
recv_ctx.phase = Phase_Wasm_Section_Type; recv_ctx.phase = Phase_Wasm_Section_Type;
recv_ctx.size_in_phase = 0; recv_ctx.size_in_phase = 0;
} }
return true; return true;
} else if (recv_ctx.phase == Phase_Wasm_Section_Type) { }
else if (recv_ctx.phase == Phase_Wasm_Section_Type) {
wasm_section_t *new_section; wasm_section_t *new_section;
if (!(new_section = (wasm_section_t *) bh_malloc(sizeof(wasm_section_t)))) if (!(new_section = (wasm_section_t *) bh_malloc(sizeof(wasm_section_t))))
@ -808,7 +864,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
if (NULL == recv_ctx.message.wasm_app_binary.sections) { if (NULL == recv_ctx.message.wasm_app_binary.sections) {
recv_ctx.message.wasm_app_binary.sections = new_section; recv_ctx.message.wasm_app_binary.sections = new_section;
recv_ctx.message.wasm_app_binary.section_end = new_section; recv_ctx.message.wasm_app_binary.section_end = new_section;
} else { }
else {
recv_ctx.message.wasm_app_binary.section_end->next = new_section; recv_ctx.message.wasm_app_binary.section_end->next = new_section;
recv_ctx.message.wasm_app_binary.section_end = new_section; recv_ctx.message.wasm_app_binary.section_end = new_section;
} }
@ -817,7 +874,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
recv_ctx.size_in_phase = 0; recv_ctx.size_in_phase = 0;
return true; return true;
} else if (recv_ctx.phase == Phase_Wasm_Section_Size) { }
else if (recv_ctx.phase == Phase_Wasm_Section_Size) {
/* the last section is the current receiving one */ /* the last section is the current receiving one */
wasm_section_t *section = recv_ctx.message.wasm_app_binary.section_end; wasm_section_t *section = recv_ctx.message.wasm_app_binary.section_end;
uint32 byte; uint32 byte;
@ -830,8 +888,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
<< recv_ctx.size_in_phase * 7); << recv_ctx.size_in_phase * 7);
recv_ctx.size_in_phase++; recv_ctx.size_in_phase++;
/* check leab128 overflow for uint32 value */ /* check leab128 overflow for uint32 value */
if (recv_ctx.size_in_phase if (recv_ctx.size_in_phase >
> (sizeof(section->section_body_size) * 8 + 7 - 1) / 7) { (sizeof(section->section_body_size) * 8 + 7 - 1) / 7) {
app_manager_printf(" LEB overflow when parsing section size\n"); app_manager_printf(" LEB overflow when parsing section size\n");
goto fail; goto fail;
} }
@ -845,7 +903,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
} }
return true; return true;
} else if (recv_ctx.phase == Phase_Wasm_Section_Content) { }
else if (recv_ctx.phase == Phase_Wasm_Section_Content) {
/* the last section is the current receiving one */ /* the last section is the current receiving one */
wasm_section_t *section = recv_ctx.message.wasm_app_binary.section_end; wasm_section_t *section = recv_ctx.message.wasm_app_binary.section_end;
@ -861,9 +920,11 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
recv_ctx.message.request_url = NULL; recv_ctx.message.request_url = NULL;
memset(&recv_ctx, 0, sizeof(recv_ctx)); memset(&recv_ctx, 0, sizeof(recv_ctx));
return true; return true;
} else }
else
goto fail; goto fail;
} else { }
else {
recv_ctx.phase = Phase_Wasm_Section_Type; recv_ctx.phase = Phase_Wasm_Section_Type;
recv_ctx.size_in_phase = 0; recv_ctx.size_in_phase = 0;
return true; return true;
@ -873,7 +934,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
return true; return true;
} }
fail: if (recv_ctx.message.wasm_app_binary.sections != NULL) { fail:
if (recv_ctx.message.wasm_app_binary.sections != NULL) {
destroy_wasm_sections_list(recv_ctx.message.wasm_app_binary.sections); destroy_wasm_sections_list(recv_ctx.message.wasm_app_binary.sections);
recv_ctx.message.wasm_app_binary.sections = NULL; recv_ctx.message.wasm_app_binary.sections = NULL;
} }
@ -915,7 +977,8 @@ static bool module_wasm_app_handle_install_msg(install_wasm_app_msg_t *message)
/* Request payload is set to wasm_app_file_t struct, /* Request payload is set to wasm_app_file_t struct,
* but not whole app buffer */ * but not whole app buffer */
memcpy(request->payload, &message->wasm_app_binary, request->payload_len); bh_memcpy_s(request->payload, request->payload_len,
&message->wasm_app_binary, request->payload_len);
/* Since it's a wasm app install request, so directly post to app-mgr's /* Since it's a wasm app install request, so directly post to app-mgr's
* queue. The benefit is that section list can be freed when the msg * queue. The benefit is that section list can be freed when the msg
@ -970,9 +1033,11 @@ static void destroy_wasm_section_from_list(wasm_section_t **sections, int type)
bh_free(cur->section_body); bh_free(cur->section_body);
bh_free(cur); bh_free(cur);
break; break;
} else { }
else {
prev = cur; prev = cur;
} }
cur = next; cur = next;
} }
} }

View File

@ -16,6 +16,12 @@
extern "C" { extern "C" {
#endif #endif
/* Special module IDs */
#define ID_HOST -3
#define ID_APP_MGR -2
/* Invalid module ID */
#define ID_NONE (uint32)-1
struct attr_container_t; struct attr_container_t;
/* Queue message type */ /* Queue message type */
@ -56,6 +62,7 @@ typedef struct watchdog_timer {
typedef struct module_data { typedef struct module_data {
struct module_data *next; struct module_data *next;
/* ID of the module */
uint32 id; uint32 id;
/* Type of the module */ /* Type of the module */

View File

@ -1,6 +1,10 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved. # Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
emcc -g -O3 *.c -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ clang-8 --target=wasm32 -O3 \
-s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 -o test.wasm -z stack-size=4096 -Wl,--initial-memory=65536 \
-Wl,--allow-undefined, \
-Wl,--export=main, \
-Wl,--no-threads,--strip-all,--no-entry \
-nostdlib -o test.wasm *.c
#./jeffdump -o test_wasm.h -n wasm_test_file test.wasm #./jeffdump -o test_wasm.h -n wasm_test_file test.wasm

View File

@ -20,7 +20,7 @@ int main(int argc, char **argv)
printf("buf ptr: %p\n", buf); printf("buf ptr: %p\n", buf);
sprintf(buf, "%s", "1234\n"); snprintf(buf, 1024, "%s", "1234\n");
printf("buf: %s", buf); printf("buf: %s", buf);
free(buf); free(buf);

View File

@ -1,6 +1,10 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved. # Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
emcc -g -O3 *.c -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ clang-8 --target=wasm32 -O3 \
-s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 -o test.wasm -z stack-size=4096 -Wl,--initial-memory=65536 \
-Wl,--allow-undefined, \
-Wl,--export=main, \
-Wl,--no-threads,--strip-all,--no-entry \
-nostdlib -o test.wasm *.c
#./jeffdump -o ../test_wasm.h -n wasm_test_file test.wasm #./jeffdump -o ../test_wasm.h -n wasm_test_file test.wasm

View File

@ -180,7 +180,8 @@ request_t *clone_request(request_t *request)
return req; return req;
fail: request_cleaner(req); fail:
request_cleaner(req);
return NULL; return NULL;
} }
@ -225,7 +226,8 @@ response_t * clone_response(response_t * response)
} }
return clone; return clone;
fail: response_cleaner(clone); fail:
response_cleaner(clone);
return NULL; return NULL;
} }

View File

@ -6,6 +6,7 @@
#include "app_manager_export.h" #include "app_manager_export.h"
#include "coap_ext.h" #include "coap_ext.h"
#include "wasm_export.h" #include "wasm_export.h"
#include "bh_assert.h"
extern void module_request_handler(request_t *request, void *user_data); extern void module_request_handler(request_t *request, void *user_data);
@ -47,6 +48,7 @@ wasm_register_resource(wasm_module_inst_t module_inst, int32 url_offset)
if (url != NULL) { if (url != NULL) {
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App, unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
module_inst); module_inst);
bh_assert(mod_id != ID_NONE);
am_register_resource(url, module_request_handler, mod_id); am_register_resource(url, module_request_handler, mod_id);
} }
} }
@ -73,6 +75,7 @@ wasm_post_request(wasm_module_inst_t module_inst,
// set sender to help dispatch the response to the sender ap // set sender to help dispatch the response to the sender ap
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App, unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
module_inst); module_inst);
bh_assert(mod_id != ID_NONE);
req->sender = mod_id; req->sender = mod_id;
if (req->action == COAP_EVENT) { if (req->action == COAP_EVENT) {
@ -98,6 +101,7 @@ wasm_sub_event(wasm_module_inst_t module_inst, int32 url_offset)
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App, unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
module_inst); module_inst);
bh_assert(mod_id != ID_NONE);
am_register_event(url, mod_id); am_register_event(url, mod_id);
} }
} }

View File

@ -143,27 +143,34 @@ timer_id_t
wasm_create_timer(wasm_module_inst_t module_inst, wasm_create_timer(wasm_module_inst_t module_inst,
int interval, bool is_period, bool auto_start) int interval, bool is_period, bool auto_start)
{ {
return sys_create_timer(get_wasm_timer_ctx(module_inst), interval, is_period, timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
auto_start); bh_assert(timer_ctx);
return sys_create_timer(timer_ctx, interval, is_period, auto_start);
} }
void void
wasm_timer_destroy(wasm_module_inst_t module_inst, timer_id_t timer_id) wasm_timer_destroy(wasm_module_inst_t module_inst, timer_id_t timer_id)
{ {
sys_timer_destroy(get_wasm_timer_ctx(module_inst), timer_id); timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
bh_assert(timer_ctx);
sys_timer_destroy(timer_ctx, timer_id);
} }
void void
wasm_timer_cancel(wasm_module_inst_t module_inst, timer_id_t timer_id) wasm_timer_cancel(wasm_module_inst_t module_inst, timer_id_t timer_id)
{ {
sys_timer_cancel(get_wasm_timer_ctx(module_inst), timer_id); timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
bh_assert(timer_ctx);
sys_timer_cancel(timer_ctx, timer_id);
} }
void void
wasm_timer_restart(wasm_module_inst_t module_inst, wasm_timer_restart(wasm_module_inst_t module_inst,
timer_id_t timer_id, int interval) timer_id_t timer_id, int interval)
{ {
sys_timer_restart(get_wasm_timer_ctx(module_inst), timer_id, interval); timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
bh_assert(timer_ctx);
sys_timer_restart(timer_ctx, timer_id, interval);
} }
extern uint32 get_sys_tick_ms(); extern uint32 get_sys_tick_ms();

View File

@ -60,7 +60,7 @@ int uart_open(char* device, int baudrate)
uart_fd = open(device, O_RDWR | O_NOCTTY); uart_fd = open(device, O_RDWR | O_NOCTTY);
if (uart_fd <= 0) if (uart_fd < 0)
return -1; return -1;
memset(&uart_term, 0, sizeof(uart_term)); memset(&uart_term, 0, sizeof(uart_term));

View File

@ -26,8 +26,10 @@ int udp_open(uint16 port)
addr.sin_port = htons(port); addr.sin_port = htons(port);
ret = bind(sock, (struct sockaddr*)&addr, sizeof(addr)); ret = bind(sock, (struct sockaddr*)&addr, sizeof(addr));
if (ret == -1) if (ret == -1) {
close(sock);
return -1; return -1;
}
/* Put the socket in non-blocking mode */ /* Put the socket in non-blocking mode */
if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) { if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) {

View File

@ -17,6 +17,8 @@
#include "conn_tcp.h" #include "conn_tcp.h"
#include "conn_udp.h" #include "conn_udp.h"
#include "conn_uart.h" #include "conn_uart.h"
#include "bh_common.h"
#include "bh_assert.h"
#include <unistd.h> #include <unistd.h>
#include <sys/epoll.h> #include <sys/epoll.h>
@ -214,6 +216,7 @@ static uint32 _conn_open(wasm_module_inst_t module_inst,
struct epoll_event ev; struct epoll_event ev;
uint32 module_id = app_manager_get_module_id(Module_WASM_App, uint32 module_id = app_manager_get_module_id(Module_WASM_App,
module_inst); module_inst);
bh_assert(module_id != ID_NONE);
if (get_app_conns_num(module_id) >= MAX_CONNECTION_PER_APP) if (get_app_conns_num(module_id) >= MAX_CONNECTION_PER_APP)
return -1; return -1;
@ -242,7 +245,7 @@ static uint32 _conn_open(wasm_module_inst_t module_inst,
port = attr_container_get_as_uint16(args, "port"); port = attr_container_get_as_uint16(args, "port");
/* Connect to TCP server */ /* Connect to TCP server */
if ((fd = tcp_open(address, port)) == -1) if (!address || (fd = tcp_open(address, port)) == -1)
goto fail; goto fail;
} else if (conn->type == CONN_TYPE_UDP) { } else if (conn->type == CONN_TYPE_UDP) {
@ -269,9 +272,10 @@ static uint32 _conn_open(wasm_module_inst_t module_inst,
baud = attr_container_get_as_int(args, "baudrate"); baud = attr_container_get_as_int(args, "baudrate");
/* Open device */ /* Open device */
if ((fd = uart_open(device, baud)) == -1) if (!device || (fd = uart_open(device, baud)) == -1)
goto fail;
} else {
goto fail; goto fail;
} }
conn->fd = fd; conn->fd = fd;
@ -345,7 +349,8 @@ static bool _conn_config(uint32 handle, attr_container_t *cfg)
if (!attr_container_contain_key(cfg, "address") || if (!attr_container_contain_key(cfg, "address") ||
!attr_container_contain_key(cfg, "port")) !attr_container_contain_key(cfg, "port"))
return false; return false;
address = attr_container_get_as_string(cfg, "address"); if (!(address = attr_container_get_as_string(cfg, "address")))
return false;
port = attr_container_get_as_uint16(cfg, "port"); port = attr_container_get_as_uint16(cfg, "port");
if (conn->arg == NULL) { if (conn->arg == NULL) {
@ -409,7 +414,7 @@ static void post_msg_to_module(sys_connection_t *conn,
bh_free(conn_data_event); bh_free(conn_data_event);
return; return;
} }
memcpy(data_copy, data, len); bh_memcpy_s(data_copy, len, data, len);
} }
memset(conn_data_event, 0, sizeof(*conn_data_event)); memset(conn_data_event, 0, sizeof(*conn_data_event));

View File

@ -0,0 +1,13 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (WASM_LIB_CONN_MGR_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${WASM_LIB_CONN_MGR_DIR})
file (GLOB_RECURSE source_all ${WASM_LIB_CONN_MGR_DIR}/*.c)
set (WASM_LIB_CONN_MGR_SOURCE ${source_all})

View File

@ -5,7 +5,10 @@ set (WASM_LIB_GUI_DIR ${CMAKE_CURRENT_LIST_DIR})
set (THIRD_PARTY_DIR ${WASM_LIB_GUI_DIR}/../../../3rdparty) set (THIRD_PARTY_DIR ${WASM_LIB_GUI_DIR}/../../../3rdparty)
include_directories(${WASM_LIB_GUI_DIR} ${THIRD_PARTY_DIR} ${THIRD_PARTY_DIR}/lvgl) include_directories(${WASM_LIB_GUI_DIR}
${THIRD_PARTY_DIR}
${THIRD_PARTY_DIR}/lvgl
${THIRD_PARTY_DIR}/lvgl/src)
file (GLOB_RECURSE lvgl_source ${THIRD_PARTY_DIR}/lvgl/*.c) file (GLOB_RECURSE lvgl_source ${THIRD_PARTY_DIR}/lvgl/*.c)
file (GLOB_RECURSE wrapper_source ${WASM_LIB_GUI_DIR}/*.c) file (GLOB_RECURSE wrapper_source ${WASM_LIB_GUI_DIR}/*.c)

View File

@ -7,6 +7,7 @@
#include "lvgl.h" #include "lvgl.h"
#include "module_wasm_app.h" #include "module_wasm_app.h"
#include "wgl_native_utils.h" #include "wgl_native_utils.h"
#include "bh_assert.h"
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* List widget native function wrappers * List widget native function wrappers
@ -24,16 +25,17 @@ lv_list_add_btn_wrapper(wasm_module_inst_t module_inst,
{ {
uint32 btn_obj_id; uint32 btn_obj_id;
lv_obj_t *btn; lv_obj_t *btn;
uint32 mod_id;
btn = lv_list_add_btn(list, NULL, text); btn = lv_list_add_btn(list, NULL, text);
if (btn == NULL) if (btn == NULL)
return 0; return 0;
if (wgl_native_add_object(btn, mod_id = app_manager_get_module_id(Module_WASM_App, module_inst);
app_manager_get_module_id(Module_WASM_App, bh_assert(mod_id != ID_NONE);
module_inst),
&btn_obj_id)) if (wgl_native_add_object(btn, mod_id, &btn_obj_id))
return btn_obj_id; /* success return */ return btn_obj_id; /* success return */
return 0; return 0;

View File

@ -4,7 +4,7 @@
#include "lvgl.h" #include "lvgl.h"
#include "module_wasm_app.h" #include "module_wasm_app.h"
#include "wasm_export.h" #include "wasm_export.h"
#include "wasm_assert.h" #include "bh_assert.h"
#include <stdint.h> #include <stdint.h>
@ -17,7 +17,8 @@ uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy,
wasm_module_inst_t module_inst) wasm_module_inst_t module_inst)
{ {
uint32 obj_id; uint32 obj_id;
lv_obj_t *wigdet; lv_obj_t *wigdet = NULL;
uint32 mod_id;
//TODO: limit total widget number //TODO: limit total widget number
@ -38,10 +39,10 @@ uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy,
if (wigdet == NULL) if (wigdet == NULL)
return 0; return 0;
if (wgl_native_add_object(wigdet, mod_id = app_manager_get_module_id(Module_WASM_App, module_inst);
app_manager_get_module_id(Module_WASM_App, bh_assert(mod_id != ID_NONE);
module_inst),
&obj_id)) if (wgl_native_add_object(wigdet, mod_id, &obj_id))
return obj_id; /* success return */ return obj_id; /* success return */
return 0; return 0;
@ -49,7 +50,7 @@ uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy,
static void invokeNative(intptr_t argv[], uint32 argc, void (*native_code)()) static void invokeNative(intptr_t argv[], uint32 argc, void (*native_code)())
{ {
wasm_assert(argc >= 1); bh_assert(argc >= 1);
switch(argc) { switch(argc) {
case 1: case 1:

View File

@ -51,6 +51,9 @@ static void app_mgr_object_event_callback(module_data *m_data, bh_message_t msg)
func_on_object_event = wasm_runtime_lookup_function(inst, "_on_widget_event", func_on_object_event = wasm_runtime_lookup_function(inst, "_on_widget_event",
"(i32i32)"); "(i32i32)");
if (!func_on_object_event)
func_on_object_event = wasm_runtime_lookup_function(inst, "on_widget_event",
"(i32i32)");
if (!func_on_object_event) { if (!func_on_object_event) {
printf("Cannot find function _on_object_event\n"); printf("Cannot find function _on_object_event\n");
return; return;

View File

@ -8,6 +8,8 @@
#include "module_wasm_app.h" #include "module_wasm_app.h"
#include "bh_thread.h" #include "bh_thread.h"
#include "bh_time.h" #include "bh_time.h"
#include "bh_common.h"
#include "bh_assert.h"
static sys_sensor_t * g_sys_sensors = NULL; static sys_sensor_t * g_sys_sensors = NULL;
static int g_sensor_id_max = 0; static int g_sensor_id_max = 0;
@ -59,7 +61,8 @@ wasm_sensor_callback(void *client, uint32 sensor_id, void *user_data)
return; return;
/* multiple sensor clients may use/free the sensor data, so make a copy */ /* multiple sensor clients may use/free the sensor data, so make a copy */
memcpy(sensor_data_clone, sensor_data, sensor_data_len); bh_memcpy_s(sensor_data_clone, sensor_data_len,
sensor_data, sensor_data_len);
sensor_event = (sensor_event_data_t *)bh_malloc(sizeof(*sensor_event)); sensor_event = (sensor_event_data_t *)bh_malloc(sizeof(*sensor_event));
if (sensor_event == NULL) { if (sensor_event == NULL) {
@ -97,6 +100,7 @@ wasm_sensor_config(wasm_module_inst_t module_inst,
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App, unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
module_inst); module_inst);
bh_assert(mod_id != ID_NONE);
vm_mutex_lock(&s->lock); vm_mutex_lock(&s->lock);
@ -147,6 +151,7 @@ wasm_sensor_open(wasm_module_inst_t module_inst,
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App, unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
module_inst); module_inst);
bh_assert(mod_id != ID_NONE);
vm_mutex_lock(&s->lock); vm_mutex_lock(&s->lock);
@ -219,6 +224,8 @@ wasm_sensor_close(wasm_module_inst_t module_inst, uint32 sensor)
sensor_obj_t s = find_sys_sensor_id(sensor); sensor_obj_t s = find_sys_sensor_id(sensor);
sensor_client_t *c; sensor_client_t *c;
bh_assert(mod_id != ID_NONE);
if (s == NULL) if (s == NULL)
return false; return false;

View File

@ -7,6 +7,10 @@
#include "wasm_export.h" #include "wasm_export.h"
#include "wasm_log.h" #include "wasm_log.h"
#include "wasm_platform_log.h" #include "wasm_platform_log.h"
#include "bh_common.h"
#if WASM_ENABLE_WASI != 0
#include "wasi_wrapper.h"
#endif
void void
wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception); wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
@ -52,7 +56,7 @@ enum pad_type {
typedef char *_va_list; typedef char *_va_list;
#define _INTSIZEOF(n) \ #define _INTSIZEOF(n) \
((sizeof(n) + 3) & ~3) (((uint32)sizeof(n) + 3) & (uint32)~3)
#define _va_arg(ap, t) \ #define _va_arg(ap, t) \
(*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))) (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
@ -86,7 +90,7 @@ _printf_hex_uint(out_func_t out, void *ctx,
if (nibble || found_largest_digit || size == 1) { if (nibble || found_largest_digit || size == 1) {
found_largest_digit = 1; found_largest_digit = 1;
nibble += nibble > 9 ? 87 : 48; nibble = (char)(nibble + (nibble > 9 ? 87 : 48));
out((int) nibble, ctx); out((int) nibble, ctx);
digits++; digits++;
continue; continue;
@ -250,7 +254,7 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
d = -d; d = -d;
min_width--; min_width--;
} }
_printf_dec_uint(out, ctx, d, padding, min_width); _printf_dec_uint(out, ctx, (uint32)d, padding, min_width);
break; break;
} }
case 'u': { case 'u': {
@ -301,8 +305,8 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
char *start; char *start;
int32 s_offset; int32 s_offset;
CHECK_VA_ARG(ap, uint32); CHECK_VA_ARG(ap, int32);
s_offset = _va_arg(ap, uint32); s_offset = _va_arg(ap, int32);
if (!validate_app_str_addr(s_offset)) { if (!validate_app_str_addr(s_offset)) {
return false; return false;
@ -314,7 +318,7 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
out((int) (*s++), ctx); out((int) (*s++), ctx);
if (padding == PAD_SPACE_AFTER) { if (padding == PAD_SPACE_AFTER) {
int remaining = min_width - (s - start); int remaining = min_width - (int32)(s - start);
while (remaining-- > 0) { while (remaining-- > 0) {
out(' ', ctx); out(' ', ctx);
} }
@ -356,8 +360,8 @@ fail:
struct str_context { struct str_context {
char *str; char *str;
int max; uint32 max;
int count; uint32 count;
}; };
static int static int
@ -371,7 +375,7 @@ sprintf_out(int c, struct str_context *ctx)
if (ctx->count == ctx->max - 1) { if (ctx->count == ctx->max - 1) {
ctx->str[ctx->count++] = '\0'; ctx->str[ctx->count++] = '\0';
} else { } else {
ctx->str[ctx->count++] = c; ctx->str[ctx->count++] = (char)c;
} }
return c; return c;
@ -432,7 +436,7 @@ _printf_wrapper(wasm_module_inst_t module_inst,
if (!_vprintf_wa((out_func_t)printf_out, &ctx, fmt, va_args, module_inst)) if (!_vprintf_wa((out_func_t)printf_out, &ctx, fmt, va_args, module_inst))
return 0; return 0;
return ctx.count; return (int)ctx.count;
} }
static int static int
@ -457,7 +461,7 @@ _sprintf_wrapper(wasm_module_inst_t module_inst,
return 0; return 0;
ctx.str = str; ctx.str = str;
ctx.max = app_end_offset - str_offset; ctx.max = (uint32)(app_end_offset - str_offset);
ctx.count = 0; ctx.count = 0;
if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst)) if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst))
@ -467,12 +471,12 @@ _sprintf_wrapper(wasm_module_inst_t module_inst,
str[ctx.count] = '\0'; str[ctx.count] = '\0';
} }
return ctx.count; return (int)ctx.count;
} }
static int static int
_snprintf_wrapper(wasm_module_inst_t module_inst, _snprintf_wrapper(wasm_module_inst_t module_inst,
int32 str_offset, int32 size, int32 fmt_offset, int32 str_offset, uint32 size, int32 fmt_offset,
int32 va_list_offset) int32 va_list_offset)
{ {
struct str_context ctx; struct str_context ctx;
@ -499,7 +503,7 @@ _snprintf_wrapper(wasm_module_inst_t module_inst,
str[ctx.count] = '\0'; str[ctx.count] = '\0';
} }
return ctx.count; return (int)ctx.count;
} }
static int static int
@ -536,21 +540,28 @@ _strdup_wrapper(wasm_module_inst_t module_inst,
str = addr_app_to_native(str_offset); str = addr_app_to_native(str_offset);
if (str) { if (str) {
len = strlen(str) + 1; len = (uint32)strlen(str) + 1;
str_ret_offset = module_malloc(len); str_ret_offset = module_malloc(len);
if (str_ret_offset) { if (str_ret_offset) {
str_ret = addr_app_to_native(str_ret_offset); str_ret = addr_app_to_native(str_ret_offset);
memcpy(str_ret, str, len); bh_memcpy_s(str_ret, len, str, len);
} }
} }
return str_ret_offset; return str_ret_offset;
} }
static int32
__strdup_wrapper(wasm_module_inst_t module_inst,
int32 str_offset)
{
return _strdup_wrapper(module_inst, str_offset);
}
static int32 static int32
_memcmp_wrapper(wasm_module_inst_t module_inst, _memcmp_wrapper(wasm_module_inst_t module_inst,
int32 s1_offset, int32 s2_offset, int32 size) int32 s1_offset, int32 s2_offset, uint32 size)
{ {
void *s1, *s2; void *s1, *s2;
@ -565,7 +576,7 @@ _memcmp_wrapper(wasm_module_inst_t module_inst,
static int32 static int32
_memcpy_wrapper(wasm_module_inst_t module_inst, _memcpy_wrapper(wasm_module_inst_t module_inst,
int32 dst_offset, int32 src_offset, int32 size) int32 dst_offset, int32 src_offset, uint32 size)
{ {
void *dst, *src; void *dst, *src;
@ -578,13 +589,13 @@ _memcpy_wrapper(wasm_module_inst_t module_inst,
dst = addr_app_to_native(dst_offset); dst = addr_app_to_native(dst_offset);
src = addr_app_to_native(src_offset); src = addr_app_to_native(src_offset);
memcpy(dst, src, size); bh_memcpy_s(dst, size, src, size);
return dst_offset; return dst_offset;
} }
static int32 static int32
_memmove_wrapper(wasm_module_inst_t module_inst, _memmove_wrapper(wasm_module_inst_t module_inst,
int32 dst_offset, int32 src_offset, int32 size) int32 dst_offset, int32 src_offset, uint32 size)
{ {
void *dst, *src; void *dst, *src;
@ -600,7 +611,7 @@ _memmove_wrapper(wasm_module_inst_t module_inst,
static int32 static int32
_memset_wrapper(wasm_module_inst_t module_inst, _memset_wrapper(wasm_module_inst_t module_inst,
int32 s_offset, int32 c, int32 size) int32 s_offset, int32 c, uint32 size)
{ {
void *s; void *s;
@ -668,7 +679,7 @@ _strcpy_wrapper(wasm_module_inst_t module_inst,
return 0; return 0;
src = addr_app_to_native(src_offset); src = addr_app_to_native(src_offset);
len = strlen(src); len = (uint32)strlen(src);
if (!validate_app_addr(dst_offset, len + 1)) if (!validate_app_addr(dst_offset, len + 1))
return 0; return 0;
@ -704,7 +715,7 @@ _strlen_wrapper(wasm_module_inst_t module_inst,
return 0; return 0;
s = addr_app_to_native(s_offset); s = addr_app_to_native(s_offset);
return strlen(s); return (uint32)strlen(s);
} }
static int32 static int32
@ -719,11 +730,11 @@ _calloc_wrapper(wasm_module_inst_t module_inst,
uint32 nmemb, uint32 size) uint32 nmemb, uint32 size)
{ {
uint64 total_size = (uint64) nmemb * (uint64) size; uint64 total_size = (uint64) nmemb * (uint64) size;
uint32 ret_offset = 0; int32 ret_offset = 0;
uint8 *ret_ptr; uint8 *ret_ptr;
if (total_size > UINT32_MAX) if (total_size >= UINT32_MAX)
total_size = UINT32_MAX; return 0;
ret_offset = module_malloc((uint32)total_size); ret_offset = module_malloc((uint32)total_size);
if (ret_offset) { if (ret_offset) {
@ -743,6 +754,245 @@ _free_wrapper(wasm_module_inst_t module_inst,
return module_free(ptr_offset); return module_free(ptr_offset);
} }
static int32
_atoi_wrapper(wasm_module_inst_t module_inst,
int32 s_offset)
{
char *str;
if (!validate_app_str_addr(s_offset))
return 0;
str = addr_app_to_native(s_offset);
return atoi(str);
}
static int32
_bsearch_wrapper(wasm_module_inst_t module_inst,
int32 key_offset, /* const void * */
int32 array_offset, /* const void * */
uint32 count,
uint32 size,
int32 cmp_index)
{
wasm_runtime_set_exception(module_inst, "bsearch not implemented.");
return 0;
}
static void
_exit_wrapper(wasm_module_inst_t module_inst,
int32 status)
{
char buf[32];
snprintf(buf, sizeof(buf), "env.exit(%i)", status);
wasm_runtime_set_exception(module_inst, buf);
}
static int32
_strtol_wrapper(wasm_module_inst_t module_inst,
int32 nptr_offset, /* const char * */
int32 endptr_offset, /* char ** */
int32 base)
{
char *nptr, **endptr;
int32 num = 0;
if (!validate_app_str_addr(nptr_offset)
|| !validate_app_addr(endptr_offset, sizeof(int32)))
return 0;
nptr = addr_app_to_native(nptr_offset);
endptr = addr_app_to_native(endptr_offset);
num = (int32)strtol(nptr, endptr, base);
*(int32 *)endptr = addr_native_to_app(*endptr);
return num;
}
static uint32
_strtoul_wrapper(wasm_module_inst_t module_inst,
int32 nptr_offset, /* const char * */
int32 endptr_offset, /* char ** */
int32 base)
{
char *nptr, **endptr;
uint32 num = 0;
if (!validate_app_str_addr(nptr_offset)
|| !validate_app_addr(endptr_offset, sizeof(int32)))
return 0;
nptr = addr_app_to_native(nptr_offset);
endptr = addr_app_to_native(endptr_offset);
num = (uint32)strtoul(nptr, endptr, base);
*(int32 *)endptr = addr_native_to_app(*endptr);
return num;
}
static int32
_memchr_wrapper(wasm_module_inst_t module_inst,
int32 s_offset, /* const void * */
int32 c,
uint32 n)
{
void *s, *res;
if (!validate_app_addr(s_offset, n))
return 0;
s = (void*)addr_app_to_native(s_offset);
res = memchr(s, c, n);
return addr_native_to_app(res);
}
static int32
_strncasecmp_wrapper(wasm_module_inst_t module_inst,
int32 s1_offset, /* const char * */
int32 s2_offset, /* const char * */
uint32 n)
{
char *s1, *s2;
if (!validate_app_str_addr(s1_offset)
|| !validate_app_str_addr(s2_offset))
return 0;
s1 = addr_app_to_native(s1_offset);
s2 = addr_app_to_native(s2_offset);
return strncasecmp(s1, s2, n);
}
static uint32
_strspn_wrapper(wasm_module_inst_t module_inst,
int32 s_offset, /* const char * */
int32 accept_offset) /* const char * */
{
char *s, *accept;
if (!validate_app_str_addr(s_offset)
|| !validate_app_str_addr(accept_offset))
return 0;
s = addr_app_to_native(s_offset);
accept = addr_app_to_native(accept_offset);
return (uint32)strspn(s, accept);
}
static uint32
_strcspn_wrapper(wasm_module_inst_t module_inst,
int32 s_offset, /* const char * */
int32 reject_offset) /* const char * */
{
char *s, *reject;
if (!validate_app_str_addr(s_offset)
|| !validate_app_str_addr(reject_offset))
return 0;
s = addr_app_to_native(s_offset);
reject = addr_app_to_native(reject_offset);
return (uint32)strcspn(s, reject);
}
static int32
_strstr_wrapper(wasm_module_inst_t module_inst,
int32 s_offset, /* const char * */
int32 find_offset) /* const char * */
{
char *s, *find, *res;
if (!validate_app_str_addr(s_offset)
|| !validate_app_str_addr(find_offset))
return 0;
s = addr_app_to_native(s_offset);
find = addr_app_to_native(find_offset);
res = strstr(s, find);
return addr_native_to_app(res);
}
static int32
_isupper_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return isupper(c);
}
static int32
_isalpha_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return isalpha(c);
}
static int32
_isspace_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return isspace(c);
}
static int32
_isgraph_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return isgraph(c);
}
static int32
_isprint_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return isprint(c);
}
static int32
_isdigit_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return isdigit(c);
}
static int32
_isxdigit_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return isxdigit(c);
}
static int32
_tolower_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return tolower(c);
}
static int32
_toupper_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return toupper(c);
}
static int32
_isalnum_wrapper(wasm_module_inst_t module_inst,
int32 c)
{
return isalnum(c);
}
static void static void
setTempRet0_wrapper(wasm_module_inst_t module_inst, setTempRet0_wrapper(wasm_module_inst_t module_inst,
uint32 temp_ret) uint32 temp_ret)
@ -842,7 +1092,7 @@ _emscripten_memcpy_big_wrapper(wasm_module_inst_t module_inst,
dst = addr_app_to_native(dst_offset); dst = addr_app_to_native(dst_offset);
src = addr_app_to_native(src_offset); src = addr_app_to_native(src_offset);
memcpy(dst, src, size); bh_memcpy_s(dst, size, src, size);
return dst_offset; return dst_offset;
} }
@ -873,6 +1123,36 @@ nullFunc_X_wrapper(wasm_module_inst_t module_inst,
wasm_runtime_set_exception(module_inst, buf); wasm_runtime_set_exception(module_inst, buf);
} }
static int32
__cxa_allocate_exception_wrapper(wasm_module_inst_t module_inst,
uint32 thrown_size)
{
int32 exception = module_malloc(thrown_size);
if (!exception)
return 0;
return exception;
}
static void
__cxa_begin_catch_wrapper(wasm_module_inst_t module_inst,
int32 exception_object_offset)
{
}
static void
__cxa_throw_wrapper(wasm_module_inst_t module_inst,
int32 thrown_exception_offset,
int32 tinfo_offset,
uint32 table_elem_idx)
{
char buf[32];
snprintf(buf, sizeof(buf), "%s", "exception thrown by stdc++");
wasm_runtime_set_exception(module_inst, buf);
}
/*#define ENABLE_SPEC_TEST 1*/ /*#define ENABLE_SPEC_TEST 1*/
#ifdef ENABLE_SPEC_TEST #ifdef ENABLE_SPEC_TEST
@ -922,7 +1202,29 @@ static WASMNativeFuncDef native_func_defs[] = {
REG_NATIVE_FUNC(env, _malloc), REG_NATIVE_FUNC(env, _malloc),
REG_NATIVE_FUNC(env, _calloc), REG_NATIVE_FUNC(env, _calloc),
REG_NATIVE_FUNC(env, _strdup), REG_NATIVE_FUNC(env, _strdup),
/* clang may introduce __strdup */
REG_NATIVE_FUNC(env, __strdup),
REG_NATIVE_FUNC(env, _free), REG_NATIVE_FUNC(env, _free),
REG_NATIVE_FUNC(env, _atoi),
REG_NATIVE_FUNC(env, _bsearch),
REG_NATIVE_FUNC(env, _exit),
REG_NATIVE_FUNC(env, _strtol),
REG_NATIVE_FUNC(env, _strtoul),
REG_NATIVE_FUNC(env, _memchr),
REG_NATIVE_FUNC(env, _strncasecmp),
REG_NATIVE_FUNC(env, _strspn),
REG_NATIVE_FUNC(env, _strcspn),
REG_NATIVE_FUNC(env, _strstr),
REG_NATIVE_FUNC(env, _isupper),
REG_NATIVE_FUNC(env, _isalpha),
REG_NATIVE_FUNC(env, _isspace),
REG_NATIVE_FUNC(env, _isgraph),
REG_NATIVE_FUNC(env, _isprint),
REG_NATIVE_FUNC(env, _isdigit),
REG_NATIVE_FUNC(env, _isxdigit),
REG_NATIVE_FUNC(env, _tolower),
REG_NATIVE_FUNC(env, _toupper),
REG_NATIVE_FUNC(env, _isalnum),
REG_NATIVE_FUNC(env, setTempRet0), REG_NATIVE_FUNC(env, setTempRet0),
REG_NATIVE_FUNC(env, getTempRet0), REG_NATIVE_FUNC(env, getTempRet0),
REG_NATIVE_FUNC(env, _llvm_bswap_i16), REG_NATIVE_FUNC(env, _llvm_bswap_i16),
@ -934,7 +1236,10 @@ static WASMNativeFuncDef native_func_defs[] = {
REG_NATIVE_FUNC(env, _emscripten_memcpy_big), REG_NATIVE_FUNC(env, _emscripten_memcpy_big),
REG_NATIVE_FUNC(env, abort), REG_NATIVE_FUNC(env, abort),
REG_NATIVE_FUNC(env, abortStackOverflow), REG_NATIVE_FUNC(env, abortStackOverflow),
REG_NATIVE_FUNC(env, nullFunc_X) REG_NATIVE_FUNC(env, nullFunc_X),
REG_NATIVE_FUNC(env, __cxa_allocate_exception),
REG_NATIVE_FUNC(env, __cxa_begin_catch),
REG_NATIVE_FUNC(env, __cxa_throw)
}; };
void* void*
@ -960,6 +1265,11 @@ wasm_native_func_lookup(const char *module_name, const char *func_name)
if ((ret = wasm_platform_native_func_lookup(module_name, func_name))) if ((ret = wasm_platform_native_func_lookup(module_name, func_name)))
return ret; return ret;
#if WASM_ENABLE_WASI != 0
if ((ret = wasi_native_func_lookup(module_name, func_name)))
return ret;
#endif
return NULL; return NULL;
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _WASI_WRAPPER_H
#define _WASI_WRAPPER_H
#include "wasmtime_ssp.h"
#include "posix.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef __wasi_errno_t wasi_errno_t;
typedef __wasi_fd_t wasi_fd_t;
typedef __wasi_clockid_t wasi_clockid_t;
typedef __wasi_timestamp_t wasi_timestamp_t;
typedef __wasi_prestat_t wasi_prestat_t;
typedef __wasi_iovec_t wasi_iovec_t;
typedef __wasi_ciovec_t wasi_ciovec_t;
typedef __wasi_filetype_t wasi_filetype_t;
typedef __wasi_filesize_t wasi_filesize_t;
typedef __wasi_filedelta_t wasi_filedelta_t;
typedef __wasi_whence_t wasi_whence_t;
typedef __wasi_fdstat_t wasi_fdstat_t;
typedef __wasi_fdflags_t wasi_fdflags_t;
typedef __wasi_rights_t wasi_rights_t;
typedef __wasi_advice_t wasi_advice_t;
typedef __wasi_lookupflags_t wasi_lookupflags_t;
typedef __wasi_oflags_t wasi_oflags_t;
typedef __wasi_dircookie_t wasi_dircookie_t;
typedef __wasi_filestat_t wasi_filestat_t;
typedef __wasi_fstflags_t wasi_fstflags_t;
typedef __wasi_subscription_t wasi_subscription_t;
typedef __wasi_event_t wasi_event_t;
typedef __wasi_exitcode_t wasi_exitcode_t;
typedef __wasi_signal_t wasi_signal_t;
typedef __wasi_riflags_t wasi_riflags_t;
typedef __wasi_roflags_t wasi_roflags_t;
typedef __wasi_siflags_t wasi_siflags_t;
typedef __wasi_sdflags_t wasi_sdflags_t;
typedef __wasi_dircookie_t wasi_dircookie_t;
typedef __wasi_preopentype_t wasi_preopentype_t;
void*
wasi_native_func_lookup(const char *module_name, const char *func_name);
#ifdef __cplusplus
}
#endif
#endif /* end of _WASI_WRAPPER_H */

View File

@ -26,6 +26,7 @@ $(NAME)_SOURCES := ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c \
${IWASM_ROOT}/lib/native/libc/libc_wrapper.c \ ${IWASM_ROOT}/lib/native/libc/libc_wrapper.c \
${IWASM_ROOT}/lib/native/base/base_lib_export.c \ ${IWASM_ROOT}/lib/native/base/base_lib_export.c \
${SHARED_LIB_ROOT}/platform/alios/bh_platform.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_platform.c \
${SHARED_LIB_ROOT}/platform/alios/bh_definition.c \
${SHARED_LIB_ROOT}/platform/alios/bh_assert.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_assert.c \
${SHARED_LIB_ROOT}/platform/alios/bh_thread.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_thread.c \
${SHARED_LIB_ROOT}/platform/alios/bh_math.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_math.c \

View File

@ -48,7 +48,7 @@ static char global_heap_buf[256 * 1024] = { 0 };
void iwasm_main(void *arg1) void iwasm_main(void *arg1)
{ {
uint8 *wasm_file_buf = NULL; uint8 *wasm_file_buf = NULL;
int wasm_file_size; uint32 wasm_file_size;
wasm_module_t wasm_module = NULL; wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL; wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128]; char error_buf[128];

View File

@ -3,6 +3,11 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/ */
/**
* The byte array buffer is the file content of a test wasm binary file,
* which is compiled by emcc or clang toolchain from C source file of:
* core/iwasm/app-samples/hello-world/main.c.
*/
unsigned char wasm_test_file[] = { 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, unsigned char wasm_test_file[] = { 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00,
0x00, 0x00, 0x0D, 0x06, 0x64, 0x79, 0x6C, 0x69, 0x6E, 0x6B, 0xC0, 0x80, 0x00, 0x00, 0x0D, 0x06, 0x64, 0x79, 0x6C, 0x69, 0x6E, 0x6B, 0xC0, 0x80,
0x04, 0x04, 0x00, 0x00, 0x01, 0x13, 0x04, 0x60, 0x01, 0x7F, 0x00, 0x60, 0x04, 0x04, 0x00, 0x00, 0x01, 0x13, 0x04, 0x60, 0x01, 0x7F, 0x00, 0x60,

View File

@ -17,7 +17,7 @@ endif ()
# Set BUILD_TARGET, currently values supported: # Set BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32" # "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32"
if (NOT BUILD_TARGET) if (NOT DEFINED BUILD_TARGET)
if (CMAKE_SIZEOF_VOID_P EQUAL 8) if (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform # Build as X86_64 by default in 64-bit platform
set (BUILD_TARGET "X86_64") set (BUILD_TARGET "X86_64")
@ -60,6 +60,19 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
endif () endif ()
endif () endif ()
if (NOT DEFINED WASM_ENABLE_WASI)
# Enable wasi support by default
set (WASM_ENABLE_WASI 1)
endif ()
if (WASM_ENABLE_WASI EQUAL 1)
add_definitions(-DWASM_ENABLE_WASI=1)
add_definitions(-D_GNU_SOURCE)
message ("-- WASI enabled")
else ()
message ("-- WASI disabled")
endif ()
if (NOT CMAKE_BUILD_TYPE) if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif (NOT CMAKE_BUILD_TYPE) endif (NOT CMAKE_BUILD_TYPE)
@ -82,6 +95,7 @@ enable_language (ASM)
include (../../runtime/platform/${PLATFORM}/platform.cmake) include (../../runtime/platform/${PLATFORM}/platform.cmake)
include (../../runtime/utils/utils.cmake) include (../../runtime/utils/utils.cmake)
include (../../runtime/vmcore-wasm/vmcore.cmake) include (../../runtime/vmcore-wasm/vmcore.cmake)
include (../../runtime/wasmtime-wasi-c/wasi.cmake)
include (../../lib/native/base/wasm_lib_base.cmake) include (../../lib/native/base/wasm_lib_base.cmake)
include (../../lib/native/libc/wasm_libc.cmake) include (../../lib/native/libc/wasm_libc.cmake)
include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake) include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
@ -92,6 +106,7 @@ add_library (vmlib
${WASM_PLATFORM_LIB_SOURCE} ${WASM_PLATFORM_LIB_SOURCE}
${WASM_UTILS_LIB_SOURCE} ${WASM_UTILS_LIB_SOURCE}
${VMCORE_LIB_SOURCE} ${VMCORE_LIB_SOURCE}
${WASI_LIB_SOURCE}
${WASM_LIB_BASE_DIR}/base_lib_export.c ${WASM_LIB_BASE_DIR}/base_lib_export.c
${WASM_LIBC_SOURCE} ${WASM_LIBC_SOURCE}
${PLATFORM_SHARED_SOURCE} ${PLATFORM_SHARED_SOURCE}

View File

@ -34,6 +34,15 @@ static int print_help()
#endif #endif
wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n" wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
" that runs commands in the form of `FUNC ARG...`\n"); " that runs commands in the form of `FUNC ARG...`\n");
#if WASM_ENABLE_WASI != 0
wasm_printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
wasm_printf(" to the program, for example:\n");
wasm_printf(" --env=\"key1=value1\" --env=\"key2=value2\"\n");
wasm_printf(" --dir=<dir> Grant wasi access to the given host directories\n");
wasm_printf(" to the program, for example:\n");
wasm_printf(" --dir=<dir1> --dir=<dir2>\n");
#endif
return 1; return 1;
} }
@ -49,7 +58,7 @@ app_instance_main(wasm_module_inst_t module_inst)
} }
static void* static void*
app_instance_func(wasm_module_inst_t module_inst, const char *func_name) app_instance_func(wasm_module_inst_t module_inst, char *func_name)
{ {
const char *exception; const char *exception;
@ -77,7 +86,7 @@ split_string(char *str, int *count)
do { do {
p = strtok(str, " "); p = strtok(str, " ");
str = NULL; str = NULL;
res = (char**) realloc(res, sizeof(char*) * (idx + 1)); res = (char**) realloc(res, sizeof(char*) * (uint32)(idx + 1));
if (res == NULL) { if (res == NULL) {
return NULL; return NULL;
} }
@ -120,6 +129,23 @@ app_instance_repl(wasm_module_inst_t module_inst)
return NULL; return NULL;
} }
static bool
validate_env_str(char *env)
{
char *p = env;
int key_len = 0;
while (*p != '\0' && *p != '=') {
key_len++;
p++;
}
if (*p != '=' || key_len == 0)
return false;
return true;
}
#define USE_GLOBAL_HEAP_BUF 0 #define USE_GLOBAL_HEAP_BUF 0
#if USE_GLOBAL_HEAP_BUF != 0 #if USE_GLOBAL_HEAP_BUF != 0
@ -129,9 +155,9 @@ static char global_heap_buf[10 * 1024 * 1024] = { 0 };
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *wasm_file = NULL; char *wasm_file = NULL;
const char *func_name = NULL; char *func_name = NULL;
uint8 *wasm_file_buf = NULL; uint8 *wasm_file_buf = NULL;
int wasm_file_size; uint32 wasm_file_size;
wasm_module_t wasm_module = NULL; wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL; wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128]; char error_buf[128];
@ -139,6 +165,12 @@ int main(int argc, char *argv[])
int log_verbose_level = 1; int log_verbose_level = 1;
#endif #endif
bool is_repl_mode = false; bool is_repl_mode = false;
#if WASM_ENABLE_WASI != 0
const char *dir_list[8] = { NULL };
uint32 dir_list_size = 0;
const char *env_list[8] = { NULL };
uint32 env_list_size = 0;
#endif
/* Process options. */ /* Process options. */
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
@ -159,6 +191,37 @@ int main(int argc, char *argv[])
#endif #endif
else if (!strcmp(argv[0], "--repl")) else if (!strcmp(argv[0], "--repl"))
is_repl_mode = true; is_repl_mode = true;
#if WASM_ENABLE_WASI != 0
else if (!strncmp(argv[0], "--dir=", 6)) {
if (argv[0][6] == '\0')
return print_help();
if (dir_list_size >= sizeof(dir_list) / sizeof(char*)) {
wasm_printf("Only allow max dir number %d\n",
(int)(sizeof(dir_list) / sizeof(char*)));
return -1;
}
dir_list[dir_list_size++] = argv[0] + 6;
}
else if (!strncmp(argv[0], "--env=", 6)) {
char *tmp_env;
if (argv[0][6] == '\0')
return print_help();
if (env_list_size >= sizeof(env_list) / sizeof(char*)) {
wasm_printf("Only allow max env number %d\n",
(int)(sizeof(env_list) / sizeof(char*)));
return -1;
}
tmp_env = argv[0] + 6;
if (validate_env_str(tmp_env))
env_list[env_list_size++] = tmp_env;
else {
wasm_printf("Wasm parse env string failed: expect \"key=value\", got \"%s\"\n",
tmp_env);
return print_help();
}
}
#endif
else else
return print_help(); return print_help();
} }
@ -201,6 +264,14 @@ int main(int argc, char *argv[])
goto fail3; goto fail3;
} }
#if WASM_ENABLE_WASI != 0
wasm_runtime_set_wasi_args(wasm_module,
dir_list, dir_list_size,
NULL, 0,
env_list, env_list_size,
argv, argc);
#endif
/* instantiate the module */ /* instantiate the module */
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
64 * 1024, /* stack size */ 64 * 1024, /* stack size */

View File

@ -22,7 +22,7 @@ if (NOT ("$ENV{VALGRIND}" STREQUAL "YES"))
endif () endif ()
# Set BUILD_TARGET, currently values supported: # Set BUILD_TARGET, currently values supported:
if (NOT BUILD_TARGET) if (NOT DEFINED BUILD_TARGET)
if (CMAKE_SIZEOF_VOID_P EQUAL 8) if (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform # Build as X86_64 by default in 64-bit platform
set (BUILD_TARGET "X86_64") set (BUILD_TARGET "X86_64")
@ -62,6 +62,19 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
endif () endif ()
endif () endif ()
if (NOT DEFINED WASM_ENABLE_WASI)
# Disable wasi support by default
set (WASM_ENABLE_WASI 0)
endif ()
if (WASM_ENABLE_WASI EQUAL 1)
add_definitions(-DWASM_ENABLE_WASI=1)
add_definitions(-D_GNU_SOURCE)
message ("-- WASI enabled")
else ()
message ("-- WASI disabled")
endif ()
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic")
@ -78,6 +91,7 @@ enable_language (ASM)
include (../../runtime/platform/${PLATFORM}/platform.cmake) include (../../runtime/platform/${PLATFORM}/platform.cmake)
include (../../runtime/utils/utils.cmake) include (../../runtime/utils/utils.cmake)
include (../../runtime/vmcore-wasm/vmcore.cmake) include (../../runtime/vmcore-wasm/vmcore.cmake)
include (../../runtime/wasmtime-wasi-c/wasi.cmake)
include (../../lib/native/base/wasm_lib_base.cmake) include (../../lib/native/base/wasm_lib_base.cmake)
include (../../lib/native/libc/wasm_libc.cmake) include (../../lib/native/libc/wasm_libc.cmake)
include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake) include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
@ -88,6 +102,7 @@ add_library (vmlib
${WASM_PLATFORM_LIB_SOURCE} ${WASM_PLATFORM_LIB_SOURCE}
${WASM_UTILS_LIB_SOURCE} ${WASM_UTILS_LIB_SOURCE}
${VMCORE_LIB_SOURCE} ${VMCORE_LIB_SOURCE}
${WASI_LIB_SOURCE}
${WASM_LIB_BASE_DIR}/base_lib_export.c ${WASM_LIB_BASE_DIR}/base_lib_export.c
${WASM_LIBC_SOURCE} ${WASM_LIBC_SOURCE}
${PLATFORM_SHARED_SOURCE} ${PLATFORM_SHARED_SOURCE}
@ -95,3 +110,7 @@ add_library (vmlib
${UTILS_SHARED_SOURCE}) ${UTILS_SHARED_SOURCE})
add_library (extlib ext_lib_export.c) add_library (extlib ext_lib_export.c)
set (copy_libs_cmd cp -a libvmlib.a libextlib.a ../enclave-sample/)
add_custom_target (copy_libs_to_enclave ALL COMMAND ${copy_libs_cmd} DEPENDS vmlib extlib)

View File

@ -0,0 +1,130 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <pwd.h>
#include "Enclave_u.h"
#include "sgx_urts.h"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define TOKEN_FILENAME "enclave.token"
#define ENCLAVE_FILENAME "enclave.signed.so"
#define MAX_PATH FILENAME_MAX
sgx_enclave_id_t g_eid = 0;
void
ocall_print(const char* str)
{
printf("%s", str);
}
static void
print_error_message(sgx_status_t ret)
{
printf("SGX error code: %d\n", ret);
}
/* Initialize the enclave:
* Step 1: try to retrieve the launch token saved by last transaction
* Step 2: call sgx_create_enclave to initialize an enclave instance
* Step 3: save the launch token if it is updated
*/
static int
enclave_init(sgx_enclave_id_t *p_eid)
{
char token_path[MAX_PATH] = {'\0'};
sgx_launch_token_t token = {0};
sgx_status_t ret = SGX_ERROR_UNEXPECTED;
int updated = 0;
/* Step 1: try to retrieve the launch token saved by last transaction
* if there is no token, then create a new one.
*/
/* try to get the token saved in $HOME */
const char *home_dir = getpwuid(getuid())->pw_dir;
if (home_dir != NULL &&
(strlen(home_dir) + strlen("/") + sizeof(TOKEN_FILENAME) + 1) <= MAX_PATH) {
/* compose the token path */
strncpy(token_path, home_dir, strlen(home_dir));
strncat(token_path, "/", strlen("/"));
strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME) + 1);
}
else {
/* if token path is too long or $HOME is NULL */
strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
}
FILE *fp = fopen(token_path, "rb");
if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
}
if (fp != NULL) {
/* read the token from saved file */
size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
/* if token is invalid, clear the buffer */
memset(&token, 0x0, sizeof(sgx_launch_token_t));
printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
}
}
/* Step 2: call sgx_create_enclave to initialize an enclave instance */
/* Debug Support: set 2nd parameter to 1 */
ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, p_eid, NULL);
if (ret != SGX_SUCCESS) {
print_error_message(ret);
if (fp != NULL)
fclose(fp);
return -1;
}
/* Step 3: save the launch token if it is updated */
if (updated == FALSE || fp == NULL) {
/* if the token is not updated, or file handler is invalid, do not perform saving */
if (fp != NULL) fclose(fp);
return 0;
}
/* reopen the file with write capablity */
fp = freopen(token_path, "wb", fp);
if (fp == NULL)
return 0;
size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
if (write_num != sizeof(sgx_launch_token_t))
printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
fclose(fp);
return 0;
}
int
main(int argc, char const *argv[])
{
if (enclave_init(&g_eid) < 0) {
std::cout << "Fail to initialize enclave." << std::endl;
return 1;
}
ecall_iwasm_main(g_eid);
return 0;
}

View File

@ -0,0 +1,12 @@
<!-- Please refer to User's Guide for the explanation of each field -->
<EnclaveConfiguration>
<ProdID>0</ProdID>
<ISVSVN>0</ISVSVN>
<StackMaxSize>0x40000</StackMaxSize>
<HeapMaxSize>0x100000</HeapMaxSize>
<TCSNum>10</TCSNum>
<TCSPolicy>1</TCSPolicy>
<DisableDebug>0</DisableDebug>
<MiscSelect>0</MiscSelect>
<MiscMask>0xFFFFFFFF</MiscMask>
</EnclaveConfiguration>

View File

@ -0,0 +1,106 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#include <string.h>
#include "Enclave_t.h"
#include "test_wasm.h"
#include "bh_memory.h"
#include "wasm_export.h"
#include "wasm_application.h"
static char global_heap_buf[512 * 1024] = { 0 };
static int app_argc;
static char **app_argv;
static void*
app_instance_main(wasm_module_inst_t module_inst)
{
const char *exception;
wasm_application_execute_main(module_inst, app_argc, app_argv);
if ((exception = wasm_runtime_get_exception(module_inst))) {
ocall_print(exception);
ocall_print("\n");
}
return NULL;
}
extern "C" {
int bh_printf(const char *message, ...);
typedef void (*bh_print_function_t)(const char* message);
extern void bh_set_print_function(bh_print_function_t pf);
void enclave_print(const char *message)
{
ocall_print(message);
}
}
void ecall_iwasm_main()
{
bh_set_print_function(enclave_print);
uint8_t *wasm_file_buf = NULL;
int wasm_file_size;
wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128];
if (bh_memory_init_with_pool(global_heap_buf,
sizeof(global_heap_buf)) != 0) {
ocall_print("Init global heap failed.\n");
return;
}
/* initialize runtime environment */
if (!wasm_runtime_init())
goto fail1;
/* load WASM byte buffer from byte buffer of include file */
wasm_file_buf = (uint8_t*) wasm_test_file;
wasm_file_size = sizeof(wasm_test_file);
/* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
error_buf, sizeof(error_buf)))) {
ocall_print(error_buf);
ocall_print("\n");
goto fail2;
}
/* instantiate the module */
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
16 * 1024,
16 * 1024,
error_buf,
sizeof(error_buf)))) {
ocall_print(error_buf);
ocall_print("\n");
goto fail3;
}
/* execute the main function of wasm app */
app_instance_main(wasm_module_inst);
/* destroy the module instance */
wasm_runtime_deinstantiate(wasm_module_inst);
fail3:
/* unload the module */
wasm_runtime_unload(wasm_module);
fail2:
/* destroy runtime environment */
wasm_runtime_destroy();
fail1:
bh_memory_destroy();
}

View File

@ -0,0 +1,16 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
enclave {
trusted {
/* define ECALLs here. */
public void ecall_iwasm_main(void);
};
untrusted {
/* define OCALLs here. */
void ocall_print([in, string]const char* str);
};
};

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ
AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ
ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr
nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b
3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H
ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD
5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW
KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC
1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe
K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z
AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q
ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6
JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826
5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02
wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9
osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm
WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i
Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9
xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd
vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD
Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a
cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC
0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ
gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo
gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t
k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz
Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6
O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5
afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom
e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G
BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv
fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN
t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9
yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp
6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg
WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH
NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk=
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
/**
* The byte array buffer is the file content of a test wasm binary file,
* which is compiled by emcc or clang toolchain from C source file of:
* core/iwasm/app-samples/hello-world/main.c.
*/
unsigned char wasm_test_file[] = { 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00,
0x00, 0x00, 0x0D, 0x06, 0x64, 0x79, 0x6C, 0x69, 0x6E, 0x6B, 0xC0, 0x80,
0x04, 0x04, 0x00, 0x00, 0x01, 0x13, 0x04, 0x60, 0x01, 0x7F, 0x00, 0x60,
0x01, 0x7F, 0x01, 0x7F, 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x60, 0x00,
0x00, 0x02, 0x58, 0x06, 0x03, 0x65, 0x6E, 0x76, 0x05, 0x5F, 0x66, 0x72,
0x65, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x07, 0x5F, 0x6D, 0x61,
0x6C, 0x6C, 0x6F, 0x63, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76, 0x07, 0x5F,
0x70, 0x72, 0x69, 0x6E, 0x74, 0x66, 0x00, 0x02, 0x03, 0x65, 0x6E, 0x76,
0x05, 0x5F, 0x70, 0x75, 0x74, 0x73, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76,
0x0D, 0x5F, 0x5F, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x5F, 0x62, 0x61,
0x73, 0x65, 0x03, 0x7F, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x6D, 0x65,
0x6D, 0x6F, 0x72, 0x79, 0x02, 0x00, 0x01, 0x03, 0x04, 0x03, 0x02, 0x03,
0x03, 0x06, 0x10, 0x03, 0x7F, 0x01, 0x41, 0x00, 0x0B, 0x7F, 0x01, 0x41,
0x00, 0x0B, 0x7F, 0x00, 0x41, 0x1B, 0x0B, 0x07, 0x33, 0x04, 0x12, 0x5F,
0x5F, 0x70, 0x6F, 0x73, 0x74, 0x5F, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6E,
0x74, 0x69, 0x61, 0x74, 0x65, 0x00, 0x06, 0x05, 0x5F, 0x6D, 0x61, 0x69,
0x6E, 0x00, 0x04, 0x0B, 0x72, 0x75, 0x6E, 0x50, 0x6F, 0x73, 0x74, 0x53,
0x65, 0x74, 0x73, 0x00, 0x05, 0x04, 0x5F, 0x73, 0x74, 0x72, 0x03, 0x03,
0x0A, 0xBA, 0x01, 0x03, 0x9E, 0x01, 0x01, 0x01, 0x7F, 0x23, 0x01, 0x21,
0x00, 0x23, 0x01, 0x41, 0x10, 0x6A, 0x24, 0x01, 0x20, 0x00, 0x41, 0x08,
0x6A, 0x21, 0x02, 0x23, 0x00, 0x41, 0x1B, 0x6A, 0x10, 0x03, 0x1A, 0x41,
0x80, 0x08, 0x10, 0x01, 0x21, 0x01, 0x20, 0x01, 0x04, 0x7F, 0x20, 0x00,
0x20, 0x01, 0x36, 0x02, 0x00, 0x23, 0x00, 0x20, 0x00, 0x10, 0x02, 0x1A,
0x20, 0x01, 0x23, 0x00, 0x2C, 0x00, 0x0D, 0x3A, 0x00, 0x00, 0x20, 0x01,
0x23, 0x00, 0x2C, 0x00, 0x0E, 0x3A, 0x00, 0x01, 0x20, 0x01, 0x23, 0x00,
0x2C, 0x00, 0x0F, 0x3A, 0x00, 0x02, 0x20, 0x01, 0x23, 0x00, 0x2C, 0x00,
0x10, 0x3A, 0x00, 0x03, 0x20, 0x01, 0x23, 0x00, 0x2C, 0x00, 0x11, 0x3A,
0x00, 0x04, 0x20, 0x01, 0x23, 0x00, 0x2C, 0x00, 0x12, 0x3A, 0x00, 0x05,
0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0x00, 0x23, 0x00, 0x41, 0x13, 0x6A,
0x20, 0x02, 0x10, 0x02, 0x1A, 0x20, 0x01, 0x10, 0x00, 0x20, 0x00, 0x24,
0x01, 0x41, 0x00, 0x05, 0x23, 0x00, 0x41, 0x28, 0x6A, 0x10, 0x03, 0x1A,
0x20, 0x00, 0x24, 0x01, 0x41, 0x7F, 0x0B, 0x0B, 0x03, 0x00, 0x01, 0x0B,
0x14, 0x00, 0x23, 0x00, 0x41, 0x40, 0x6B, 0x24, 0x01, 0x23, 0x01, 0x41,
0x80, 0x80, 0x04, 0x6A, 0x24, 0x02, 0x10, 0x05, 0x0B, 0x0B, 0x3F, 0x01,
0x00, 0x23, 0x00, 0x0B, 0x39, 0x62, 0x75, 0x66, 0x20, 0x70, 0x74, 0x72,
0x3A, 0x20, 0x25, 0x70, 0x0A, 0x00, 0x31, 0x32, 0x33, 0x34, 0x0A, 0x00,
0x62, 0x75, 0x66, 0x3A, 0x20, 0x25, 0x73, 0x00, 0x48, 0x65, 0x6C, 0x6C,
0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00, 0x6D, 0x61, 0x6C,
0x6C, 0x6F, 0x63, 0x20, 0x62, 0x75, 0x66, 0x20, 0x66, 0x61, 0x69, 0x6C,
0x65, 0x64, 0x00, 0x50, 0x04, 0x6E, 0x61, 0x6D, 0x65, 0x01, 0x49, 0x07,
0x00, 0x05, 0x5F, 0x66, 0x72, 0x65, 0x65, 0x01, 0x07, 0x5F, 0x6D, 0x61,
0x6C, 0x6C, 0x6F, 0x63, 0x02, 0x07, 0x5F, 0x70, 0x72, 0x69, 0x6E, 0x74,
0x66, 0x03, 0x05, 0x5F, 0x70, 0x75, 0x74, 0x73, 0x04, 0x05, 0x5F, 0x6D,
0x61, 0x69, 0x6E, 0x05, 0x0B, 0x72, 0x75, 0x6E, 0x50, 0x6F, 0x73, 0x74,
0x53, 0x65, 0x74, 0x73, 0x06, 0x12, 0x5F, 0x5F, 0x70, 0x6F, 0x73, 0x74,
0x5F, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x69, 0x61, 0x74, 0x65,
0x00, 0x20, 0x10, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x4D, 0x61, 0x70,
0x70, 0x69, 0x6E, 0x67, 0x55, 0x52, 0x4C, 0x0E, 0x61, 0x2E, 0x6F, 0x75,
0x74, 0x2E, 0x77, 0x61, 0x73, 0x6D, 0x2E, 0x6D, 0x61, 0x70 };

View File

@ -0,0 +1,184 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
######## SGX SDK Settings ########
SGX_SDK ?= /opt/intel/sgxsdk
SGX_MODE ?= SIM
SGX_ARCH ?= x64
ifeq ($(shell getconf LONG_BIT), 32)
SGX_ARCH := x86
else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
SGX_ARCH := x86
endif
ifeq ($(SGX_ARCH), x86)
SGX_COMMON_CFLAGS := -m32
SGX_LIBRARY_PATH := $(SGX_SDK)/lib
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
else
SGX_COMMON_CFLAGS := -m64
SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
endif
ifeq ($(SGX_DEBUG), 1)
ifeq ($(SGX_PRERELEASE), 1)
$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
endif
endif
ifeq ($(SGX_DEBUG), 1)
SGX_COMMON_CFLAGS += -O0 -g
else
SGX_COMMON_CFLAGS += -O2
endif
######## App Settings ########
ifneq ($(SGX_MODE), HW)
Urts_Library_Name := sgx_urts_sim
else
Urts_Library_Name := sgx_urts
endif
App_Cpp_Files := App/App.cpp
App_Include_Paths := -IApp -I$(SGX_SDK)/include
App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
# Three configuration modes - Debug, prerelease, release
# Debug - Macro DEBUG enabled.
# Prerelease - Macro NDEBUG and EDEBUG enabled.
# Release - Macro NDEBUG enabled.
ifeq ($(SGX_DEBUG), 1)
App_C_Flags += -DDEBUG -UNDEBUG -UEDEBUG
else ifeq ($(SGX_PRERELEASE), 1)
App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUG
else
App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG
endif
App_Cpp_Flags := $(App_C_Flags) -std=c++11
App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread
ifneq ($(SGX_MODE), HW)
App_Link_Flags += -lsgx_uae_service_sim
else
App_Link_Flags += -lsgx_uae_service
endif
App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
App_Name := app
######## Enclave Settings ########
ifneq ($(SGX_MODE), HW)
Trts_Library_Name := sgx_trts_sim
Service_Library_Name := sgx_tservice_sim
else
Trts_Library_Name := sgx_trts
Service_Library_Name := sgx_tservice
endif
Crypto_Library_Name := sgx_tcrypto
WAMR_ROOT := $(CURDIR)/../../../../../
Enclave_Cpp_Files := Enclave/Enclave.cpp
Enclave_Include_Paths := -IEnclave -I$(WAMR_ROOT)/core/iwasm/runtime/include \
-I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport
Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths)
Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++03 -nostdinc++
Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
libvmlib.a libextlib.a \
-Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \
-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
-Wl,-pie,-eenclave_entry -Wl,--export-dynamic \
-Wl,--defsym,__ImageBase=0
Enclave_Cpp_Objects := $(Enclave_Cpp_Files:.cpp=.o)
Enclave_Name := enclave.so
Signed_Enclave_Name := enclave.signed.so
Enclave_Config_File := Enclave/Enclave.config.xml
ifeq ($(SGX_MODE), HW)
ifneq ($(SGX_DEBUG), 1)
ifneq ($(SGX_PRERELEASE), 1)
Build_Mode = HW_RELEASE
endif
endif
endif
.PHONY: all run
ifeq ($(Build_Mode), HW_RELEASE)
all: $(App_Name) $(Enclave_Name)
@echo "The project has been built in release hardware mode."
@echo "Please sign the $(Enclave_Name) first with your signing key before you run the $(App_Name) to launch and access the enclave."
@echo "To sign the enclave use the command:"
@echo " $(SGX_ENCLAVE_SIGNER) sign -key <your key> -enclave $(Enclave_Name) -out <$(Signed_Enclave_Name)> -config $(Enclave_Config_File)"
@echo "You can also sign the enclave using an external signing tool. See User's Guide for more details."
@echo "To build the project in simulation mode set SGX_MODE=SIM. To build the project in prerelease mode set SGX_PRERELEASE=1 and SGX_MODE=HW."
else
all: $(App_Name) $(Signed_Enclave_Name)
endif
run: all
ifneq ($(Build_Mode), HW_RELEASE)
@$(CURDIR)/$(App_Name)
@echo "RUN => $(App_Name) [$(SGX_MODE)|$(SGX_ARCH), OK]"
endif
######## App Objects ########
App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl
@cd App && $(SGX_EDGER8R) --untrusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include
@echo "GEN => $@"
App/Enclave_u.o: App/Enclave_u.c
@$(CC) $(App_C_Flags) -c $< -o $@
@echo "CC <= $<"
App/%.o: App/%.cpp
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
@echo "CXX <= $<"
$(App_Name): App/Enclave_u.o $(App_Cpp_Objects)
@$(CXX) $^ -o $@ $(App_Link_Flags)
@echo "LINK => $@"
######## Enclave Objects ########
Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl
@cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include
@echo "GEN => $@"
Enclave/Enclave_t.o: Enclave/Enclave_t.c
@$(CC) $(Enclave_C_Flags) -c $< -o $@
@echo "CC <= $<"
Enclave/%.o: Enclave/%.cpp
@$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@
@echo "CXX <= $<"
$(Enclave_Name): Enclave/Enclave_t.o $(Enclave_Cpp_Objects)
@$(CXX) $^ -o $@ $(Enclave_Link_Flags)
@echo "LINK => $@"
$(Signed_Enclave_Name): $(Enclave_Name)
@$(SGX_ENCLAVE_SIGNER) sign -key Enclave/Enclave_private.pem -enclave $(Enclave_Name) -out $@ -config $(Enclave_Config_File)
@echo "SIGN => $@"
.PHONY: clean
clean:
@rm -f $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/Enclave_u.* $(Enclave_Cpp_Objects) Enclave/Enclave_t.*

View File

@ -17,7 +17,7 @@ endif ()
# Set BUILD_TARGET, currently values supported: # Set BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32" # "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32"
if (NOT BUILD_TARGET) if (NOT DEFINED BUILD_TARGET)
if (CMAKE_SIZEOF_VOID_P EQUAL 8) if (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform # Build as X86_64 by default in 64-bit platform
set (BUILD_TARGET "X86_64") set (BUILD_TARGET "X86_64")
@ -60,6 +60,18 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
endif () endif ()
endif () endif ()
if (NOT DEFINED WASM_ENABLE_WASI)
# Enable wasi support by default
set (WASM_ENABLE_WASI 1)
endif ()
if (WASM_ENABLE_WASI EQUAL 1)
add_definitions(-DWASM_ENABLE_WASI=1)
message ("-- WASI enabled")
else ()
message ("-- WASI disabled")
endif ()
if (NOT CMAKE_BUILD_TYPE) if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif (NOT CMAKE_BUILD_TYPE) endif (NOT CMAKE_BUILD_TYPE)
@ -80,16 +92,26 @@ enable_language (ASM)
include (../../runtime/platform/${PLATFORM}/platform.cmake) include (../../runtime/platform/${PLATFORM}/platform.cmake)
include (../../runtime/utils/utils.cmake) include (../../runtime/utils/utils.cmake)
include (../../runtime/vmcore-wasm/vmcore.cmake) include (../../runtime/vmcore-wasm/vmcore.cmake)
include (../../runtime/wasmtime-wasi-c/wasi.cmake)
include (../../lib/native/base/wasm_lib_base.cmake) include (../../lib/native/base/wasm_lib_base.cmake)
include (../../lib/native/libc/wasm_libc.cmake) include (../../lib/native/libc/wasm_libc.cmake)
include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake) include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake) include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake)
include (${SHARED_LIB_DIR}/utils/shared_utils.cmake) include (${SHARED_LIB_DIR}/utils/shared_utils.cmake)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch=thunk -mfunction-return=thunk -mindirect-branch-register")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong --param ssp-buffer-size=4")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pie -fPIE -ftrapv -D_FORTIFY_SOURCE=2")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack,-z,relro,-z,now")
#message ("-- CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
add_library (vmlib add_library (vmlib
${WASM_PLATFORM_LIB_SOURCE} ${WASM_PLATFORM_LIB_SOURCE}
${WASM_UTILS_LIB_SOURCE} ${WASM_UTILS_LIB_SOURCE}
${VMCORE_LIB_SOURCE} ${VMCORE_LIB_SOURCE}
${WASI_LIB_SOURCE}
${WASM_LIB_BASE_DIR}/base_lib_export.c ${WASM_LIB_BASE_DIR}/base_lib_export.c
${WASM_LIBC_SOURCE} ${WASM_LIBC_SOURCE}
${PLATFORM_SHARED_SOURCE} ${PLATFORM_SHARED_SOURCE}

View File

@ -32,6 +32,15 @@ static int print_help()
#endif #endif
wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n" wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
" that runs commands in the form of `FUNC ARG...`\n"); " that runs commands in the form of `FUNC ARG...`\n");
#if WASM_ENABLE_WASI != 0
wasm_printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
wasm_printf(" to the program, for example:\n");
wasm_printf(" --env=\"key1=value1\" --env=\"key2=value2\"\n");
wasm_printf(" --dir=<dir> Grant wasi access to the given host directories\n");
wasm_printf(" to the program, for example:\n");
wasm_printf(" --dir=<dir1> --dir=<dir2>\n");
#endif
return 1; return 1;
} }
@ -104,7 +113,7 @@ split_string(char *str, int *count)
do { do {
p = strtok(str, " "); p = strtok(str, " ");
str = NULL; str = NULL;
res = (char**) realloc(res, sizeof(char*) * (idx + 1)); res = (char**) realloc(res, sizeof(char*) * (uint32)(idx + 1));
if (res == NULL) { if (res == NULL) {
return NULL; return NULL;
} }
@ -147,6 +156,23 @@ app_instance_repl(wasm_module_inst_t module_inst)
return NULL; return NULL;
} }
static bool
validate_env_str(char *env)
{
char *p = env;
int key_len = 0;
while (*p != '\0' && *p != '=') {
key_len++;
p++;
}
if (*p != '=' || key_len == 0)
return false;
return true;
}
#define USE_GLOBAL_HEAP_BUF 0 #define USE_GLOBAL_HEAP_BUF 0
#if USE_GLOBAL_HEAP_BUF != 0 #if USE_GLOBAL_HEAP_BUF != 0
@ -158,7 +184,7 @@ int main(int argc, char *argv[])
char *wasm_file = NULL; char *wasm_file = NULL;
const char *func_name = NULL; const char *func_name = NULL;
uint8 *wasm_file_buf = NULL; uint8 *wasm_file_buf = NULL;
int wasm_file_size; uint32 wasm_file_size;
wasm_module_t wasm_module = NULL; wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL; wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128]; char error_buf[128];
@ -166,6 +192,12 @@ int main(int argc, char *argv[])
int log_verbose_level = 1; int log_verbose_level = 1;
#endif #endif
bool is_repl_mode = false; bool is_repl_mode = false;
#if WASM_ENABLE_WASI != 0
const char *dir_list[8] = { NULL };
uint32 dir_list_size = 0;
const char *env_list[8] = { NULL };
uint32 env_list_size = 0;
#endif
/* Process options. */ /* Process options. */
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
@ -186,6 +218,37 @@ int main(int argc, char *argv[])
#endif #endif
else if (!strcmp(argv[0], "--repl")) else if (!strcmp(argv[0], "--repl"))
is_repl_mode = true; is_repl_mode = true;
#if WASM_ENABLE_WASI != 0
else if (!strncmp(argv[0], "--dir=", 6)) {
if (argv[0][6] == '\0')
return print_help();
if (dir_list_size >= sizeof(dir_list) / sizeof(char*)) {
wasm_printf("Only allow max dir number %d\n",
(int)(sizeof(dir_list) / sizeof(char*)));
return -1;
}
dir_list[dir_list_size++] = argv[0] + 6;
}
else if (!strncmp(argv[0], "--env=", 6)) {
char *tmp_env;
if (argv[0][6] == '\0')
return print_help();
if (env_list_size >= sizeof(env_list) / sizeof(char*)) {
wasm_printf("Only allow max env number %d\n",
(int)(sizeof(env_list) / sizeof(char*)));
return -1;
}
tmp_env = argv[0] + 6;
if (validate_env_str(tmp_env))
env_list[env_list_size++] = tmp_env;
else {
wasm_printf("Wasm parse env string failed: expect \"key=value\", got \"%s\"\n",
tmp_env);
return print_help();
}
}
#endif
else else
return print_help(); return print_help();
} }
@ -228,6 +291,14 @@ int main(int argc, char *argv[])
goto fail3; goto fail3;
} }
#if WASM_ENABLE_WASI != 0
wasm_runtime_set_wasi_args(wasm_module,
dir_list, dir_list_size,
NULL, 0,
env_list, env_list_size,
argv, argc);
#endif
/* instantiate the module */ /* instantiate the module */
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
64 * 1024, /* stack size */ 64 * 1024, /* stack size */

View File

@ -24,7 +24,7 @@ endif ()
# "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32", "GENERAL" # "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32", "GENERAL"
#set (BUILD_TARGET "X86_64") #set (BUILD_TARGET "X86_64")
if (NOT BUILD_TARGET) if (NOT DEFINED BUILD_TARGET)
if (CMAKE_SIZEOF_VOID_P EQUAL 8) if (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform # Build as X86_64 by default in 64-bit platform
# if BUILD_TARGET isn't set # if BUILD_TARGET isn't set
@ -77,6 +77,19 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
endif () endif ()
endif () endif ()
if (NOT DEFINED WASM_ENABLE_WASI)
# Enable wasi support by default
set (WASM_ENABLE_WASI 1)
endif ()
if (WASM_ENABLE_WASI EQUAL 1)
add_definitions(-DWASM_ENABLE_WASI=1)
add_definitions(-D_GNU_SOURCE)
message ("-- WASI enabled")
else ()
message ("-- WASI disabled")
endif ()
if (NOT CMAKE_BUILD_TYPE) if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif (NOT CMAKE_BUILD_TYPE) endif (NOT CMAKE_BUILD_TYPE)
@ -97,6 +110,7 @@ enable_language (ASM)
include (../../runtime/platform/${PLATFORM}/platform.cmake) include (../../runtime/platform/${PLATFORM}/platform.cmake)
include (../../runtime/utils/utils.cmake) include (../../runtime/utils/utils.cmake)
include (../../runtime/vmcore-wasm/vmcore.cmake) include (../../runtime/vmcore-wasm/vmcore.cmake)
include (../../runtime/wasmtime-wasi-c/wasi.cmake)
include (../../lib/native/base/wasm_lib_base.cmake) include (../../lib/native/base/wasm_lib_base.cmake)
include (../../lib/native/libc/wasm_libc.cmake) include (../../lib/native/libc/wasm_libc.cmake)
include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake) include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
@ -107,6 +121,7 @@ add_library (vmlib
${WASM_PLATFORM_LIB_SOURCE} ${WASM_PLATFORM_LIB_SOURCE}
${WASM_UTILS_LIB_SOURCE} ${WASM_UTILS_LIB_SOURCE}
${VMCORE_LIB_SOURCE} ${VMCORE_LIB_SOURCE}
${WASI_LIB_SOURCE}
${WASM_LIB_BASE_DIR}/base_lib_export.c ${WASM_LIB_BASE_DIR}/base_lib_export.c
${WASM_LIBC_SOURCE} ${WASM_LIBC_SOURCE}
${PLATFORM_SHARED_SOURCE} ${PLATFORM_SHARED_SOURCE}

View File

@ -32,6 +32,15 @@ static int print_help()
#endif #endif
wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n" wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
" that runs commands in the form of `FUNC ARG...`\n"); " that runs commands in the form of `FUNC ARG...`\n");
#if WASM_ENABLE_WASI != 0
wasm_printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
wasm_printf(" to the program, for example:\n");
wasm_printf(" --env=\"key1=value1\" --env=\"key2=value2\"\n");
wasm_printf(" --dir=<dir> Grant wasi access to the given host directories\n");
wasm_printf(" to the program, for example:\n");
wasm_printf(" --dir=<dir1> --dir=<dir2>\n");
#endif
return 1; return 1;
} }
@ -104,7 +113,7 @@ split_string(char *str, int *count)
do { do {
p = strtok(str, " "); p = strtok(str, " ");
str = NULL; str = NULL;
res = (char**) realloc(res, sizeof(char*) * (idx + 1)); res = (char**) realloc(res, sizeof(char*) * (uint32)(idx + 1));
if (res == NULL) { if (res == NULL) {
return NULL; return NULL;
} }
@ -147,6 +156,23 @@ app_instance_repl(wasm_module_inst_t module_inst)
return NULL; return NULL;
} }
static bool
validate_env_str(char *env)
{
char *p = env;
int key_len = 0;
while (*p != '\0' && *p != '=') {
key_len++;
p++;
}
if (*p != '=' || key_len == 0)
return false;
return true;
}
static char global_heap_buf[512 * 1024] = { 0 }; static char global_heap_buf[512 * 1024] = { 0 };
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -154,7 +180,7 @@ int main(int argc, char *argv[])
char *wasm_file = NULL; char *wasm_file = NULL;
const char *func_name = NULL; const char *func_name = NULL;
uint8 *wasm_file_buf = NULL; uint8 *wasm_file_buf = NULL;
int wasm_file_size; uint32 wasm_file_size;
wasm_module_t wasm_module = NULL; wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL; wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128]; char error_buf[128];
@ -162,6 +188,12 @@ int main(int argc, char *argv[])
int log_verbose_level = 1; int log_verbose_level = 1;
#endif #endif
bool is_repl_mode = false; bool is_repl_mode = false;
#if WASM_ENABLE_WASI != 0
const char *dir_list[8] = { NULL };
uint32 dir_list_size = 0;
const char *env_list[8] = { NULL };
uint32 env_list_size = 0;
#endif
/* Process options. */ /* Process options. */
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
@ -182,6 +214,37 @@ int main(int argc, char *argv[])
#endif #endif
else if (!strcmp(argv[0], "--repl")) else if (!strcmp(argv[0], "--repl"))
is_repl_mode = true; is_repl_mode = true;
#if WASM_ENABLE_WASI != 0
else if (!strncmp(argv[0], "--dir=", 6)) {
if (argv[0][6] == '\0')
return print_help();
if (dir_list_size >= sizeof(dir_list) / sizeof(char*)) {
wasm_printf("Only allow max dir number %d\n",
(int)(sizeof(dir_list) / sizeof(char*)));
return -1;
}
dir_list[dir_list_size++] = argv[0] + 6;
}
else if (!strncmp(argv[0], "--env=", 6)) {
char *tmp_env;
if (argv[0][6] == '\0')
return print_help();
if (env_list_size >= sizeof(env_list) / sizeof(char*)) {
wasm_printf("Only allow max env number %d\n",
(int)(sizeof(env_list) / sizeof(char*)));
return -1;
}
tmp_env = argv[0] + 6;
if (validate_env_str(tmp_env))
env_list[env_list_size++] = tmp_env;
else {
wasm_printf("Wasm parse env string failed: expect \"key=value\", got \"%s\"\n",
tmp_env);
return print_help();
}
}
#endif
else else
return print_help(); return print_help();
} }
@ -217,6 +280,14 @@ int main(int argc, char *argv[])
goto fail3; goto fail3;
} }
#if WASM_ENABLE_WASI != 0
wasm_runtime_set_wasi_args(wasm_module,
dir_list, dir_list_size,
NULL, 0,
env_list, env_list_size,
argv, argc);
#endif
/* instantiate the module */ /* instantiate the module */
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
16 * 1024, /* stack size */ 16 * 1024, /* stack size */

View File

@ -8,11 +8,13 @@ project(NONE)
enable_language (ASM) enable_language (ASM)
set (PLATFORM "zephyr")
add_definitions (-DNVALGRIND) add_definitions (-DNVALGRIND)
# Build as X86_32 by default, change to "ARM_32", "MIPS_32" or "XTENSA_32" # Build as X86_32 by default, change to "ARM_32", "MIPS_32" or "XTENSA_32"
# if we want to support arm, mips or xtensa # if we want to support arm, mips or xtensa
if (NOT BUILD_TARGET) if (NOT DEFINED BUILD_TARGET)
set (BUILD_TARGET "X86_32") set (BUILD_TARGET "X86_32")
endif () endif ()
@ -35,33 +37,29 @@ message ("-- Build as target ${BUILD_TARGET}")
set (IWASM_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/iwasm) set (IWASM_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/iwasm)
set (SHARED_LIB_ROOT ${IWASM_ROOT}/../shared-lib) set (SHARED_LIB_ROOT ${IWASM_ROOT}/../shared-lib)
include_directories (${IWASM_ROOT}/runtime/include include (${IWASM_ROOT}/runtime/platform/${PLATFORM}/platform.cmake)
${IWASM_ROOT}/runtime/platform/include include (${IWASM_ROOT}/runtime/utils/utils.cmake)
${IWASM_ROOT}/runtime/platform/zephyr include (${IWASM_ROOT}/runtime/vmcore-wasm/vmcore.cmake)
${IWASM_ROOT}/runtime/vmcore-wasm include (${IWASM_ROOT}/runtime/wasmtime-wasi-c/wasi.cmake)
${SHARED_LIB_ROOT}/include include (${IWASM_ROOT}/lib/native/base/wasm_lib_base.cmake)
${SHARED_LIB_ROOT}/platform/include include (${IWASM_ROOT}/lib/native/libc/wasm_libc.cmake)
${SHARED_LIB_ROOT}/platform/zephyr) include (${SHARED_LIB_ROOT}/platform/${PLATFORM}/shared_platform.cmake)
include (${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.cmake)
include (${SHARED_LIB_ROOT}/utils/shared_utils.cmake)
set (IWASM_SRCS ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c set (VM_LIB_SRCS
${IWASM_ROOT}/runtime/utils/wasm_log.c ${WASM_PLATFORM_LIB_SOURCE}
${IWASM_ROOT}/runtime/utils/wasm_dlfcn.c ${WASM_UTILS_LIB_SOURCE}
${IWASM_ROOT}/runtime/platform/zephyr/wasm_native.c ${VMCORE_LIB_SOURCE}
${IWASM_ROOT}/runtime/vmcore-wasm/wasm_application.c ${WASI_LIB_SOURCE}
${IWASM_ROOT}/runtime/vmcore-wasm/wasm_interp.c ${WASM_LIB_BASE_DIR}/base_lib_export.c
${IWASM_ROOT}/runtime/vmcore-wasm/wasm_loader.c ${WASM_LIBC_SOURCE}
${IWASM_ROOT}/runtime/vmcore-wasm/wasm_runtime.c ${PLATFORM_SHARED_SOURCE}
${IWASM_ROOT}/runtime/vmcore-wasm/invokeNative_general.c ${MEM_ALLOC_SHARED_SOURCE}
${IWASM_ROOT}/lib/native/libc/libc_wrapper.c ${UTILS_SHARED_SOURCE})
${IWASM_ROOT}/lib/native/base/base_lib_export.c
${SHARED_LIB_ROOT}/platform/zephyr/bh_platform.c target_sources(app PRIVATE
${SHARED_LIB_ROOT}/platform/zephyr/bh_assert.c ${VM_LIB_SRCS}
${SHARED_LIB_ROOT}/platform/zephyr/bh_thread.c src/main.c
${SHARED_LIB_ROOT}/platform/zephyr/bh_math.c src/ext_lib_export.c)
${SHARED_LIB_ROOT}/mem-alloc/bh_memory.c
${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.c
${SHARED_LIB_ROOT}/mem-alloc/ems/ems_kfc.c
${SHARED_LIB_ROOT}/mem-alloc/ems/ems_alloc.c
${SHARED_LIB_ROOT}/mem-alloc/ems/ems_hmu.c)
target_sources(app PRIVATE ${IWASM_SRCS} src/main.c src/ext_lib_export.c)

View File

@ -53,7 +53,7 @@ static char global_heap_buf[CONFIG_GLOBAL_HEAP_BUF_SIZE] = { 0 };
void iwasm_main(void *arg1, void *arg2, void *arg3) void iwasm_main(void *arg1, void *arg2, void *arg3)
{ {
uint8 *wasm_file_buf = NULL; uint8 *wasm_file_buf = NULL;
int wasm_file_size; uint32 wasm_file_size;
wasm_module_t wasm_module = NULL; wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL; wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128]; char error_buf[128];

View File

@ -3,6 +3,11 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/ */
/**
* The byte array buffer is the file content of a test wasm binary file,
* which is compiled by emcc or clang toolchain from C source file of:
* core/iwasm/app-samples/hello-world/main.c.
*/
unsigned char wasm_test_file[] = { 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, unsigned char wasm_test_file[] = { 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00,
0x00, 0x00, 0x0D, 0x06, 0x64, 0x79, 0x6C, 0x69, 0x6E, 0x6B, 0xC0, 0x80, 0x00, 0x00, 0x0D, 0x06, 0x64, 0x79, 0x6C, 0x69, 0x6E, 0x6B, 0xC0, 0x80,
0x04, 0x04, 0x00, 0x00, 0x01, 0x13, 0x04, 0x60, 0x01, 0x7F, 0x00, 0x60, 0x04, 0x04, 0x00, 0x00, 0x01, 0x13, 0x04, 0x60, 0x01, 0x7F, 0x00, 0x60,

View File

@ -45,7 +45,7 @@ void bh_memory_destroy();
* Get the pool size of memory, if memory is initialized with allocator, * Get the pool size of memory, if memory is initialized with allocator,
* return 1GB by default. * return 1GB by default.
*/ */
int bh_memory_pool_size(); unsigned bh_memory_pool_size();
#if BEIHAI_ENABLE_MEMORY_PROFILING == 0 #if BEIHAI_ENABLE_MEMORY_PROFILING == 0

View File

@ -110,6 +110,15 @@ wasm_runtime_load_from_sections(wasm_section_list_t section_list,
void void
wasm_runtime_unload(wasm_module_t module); wasm_runtime_unload(wasm_module_t module);
#if WASM_ENABLE_WASI != 0
void
wasm_runtime_set_wasi_args(wasm_module_t module,
const char *dir_list[], uint32 dir_count,
const char *map_dir_list[], uint32 map_dir_count,
const char *env[], uint32 env_count,
char *argv[], int argc);
#endif
/** /**
* Instantiate a WASM module. * Instantiate a WASM module.
* *

View File

@ -12,6 +12,7 @@
#include "wasm_log.h" #include "wasm_log.h"
#include "wasm_memory.h" #include "wasm_memory.h"
#include "wasm_platform_log.h" #include "wasm_platform_log.h"
#include "bh_common.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/uio.h> #include <sys/uio.h>
@ -91,7 +92,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
uint32 iov_len; uint32 iov_len;
} *vec; } *vec;
int32 vec_offset = arg2, str_offset; int32 vec_offset = arg2, str_offset;
uint32 iov_count = arg3, i; uint32 iov_count = (uint32)arg3, i;
int32 count = 0; int32 count = 0;
char *iov_base, *str; char *iov_base, *str;
@ -110,7 +111,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
str = addr_app_to_native(str_offset); str = addr_app_to_native(str_offset);
memcpy(str, iov_base, vec->iov_len); bh_memcpy_s(str, vec->iov_len + 1, iov_base, vec->iov_len);
str[vec->iov_len] = '\0'; str[vec->iov_len] = '\0';
count += wasm_printf("%s", str); count += wasm_printf("%s", str);
@ -219,7 +220,7 @@ EMCC_SYSCALL_WRAPPER3(221)
EMCC_SYSCALL_WRAPPER5(140) EMCC_SYSCALL_WRAPPER5(140)
static int32 static uint32
getTotalMemory_wrapper(WASMModuleInstance *module_inst) getTotalMemory_wrapper(WASMModuleInstance *module_inst)
{ {
WASMMemoryInstance *memory = module_inst->default_memory; WASMMemoryInstance *memory = module_inst->default_memory;

View File

@ -1,7 +1,7 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved. # Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309L) add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE)
set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}) set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})

View File

@ -12,6 +12,7 @@
#include "wasm_log.h" #include "wasm_log.h"
#include "wasm_memory.h" #include "wasm_memory.h"
#include "wasm_platform_log.h" #include "wasm_platform_log.h"
#include "bh_common.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/uio.h> #include <sys/uio.h>
@ -92,7 +93,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
return 0; return 0;
wsz = (struct winsize*)addr_app_to_native(arg3); wsz = (struct winsize*)addr_app_to_native(arg3);
return syscall(54, arg1, arg2, wsz); return (int32)syscall(54, arg1, arg2, wsz);
} }
case 146: /* writev */ case 146: /* writev */
@ -104,7 +105,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
uint32 iov_len; uint32 iov_len;
} *vec; } *vec;
int32 vec_offset = arg2, str_offset; int32 vec_offset = arg2, str_offset;
uint32 iov_count = arg3, i; uint32 iov_count = (uint32)arg3, i;
int32 count = 0; int32 count = 0;
char *iov_base, *str; char *iov_base, *str;
@ -123,7 +124,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
str = addr_app_to_native(str_offset); str = addr_app_to_native(str_offset);
memcpy(str, iov_base, vec->iov_len); bh_memcpy_s(str, vec->iov_len + 1, iov_base, vec->iov_len);
str[vec->iov_len] = '\0'; str[vec->iov_len] = '\0';
count += wasm_printf("%s", str); count += wasm_printf("%s", str);
@ -232,7 +233,7 @@ EMCC_SYSCALL_WRAPPER3(221)
EMCC_SYSCALL_WRAPPER5(140) EMCC_SYSCALL_WRAPPER5(140)
static int32 static uint32
getTotalMemory_wrapper(WASMModuleInstance *module_inst) getTotalMemory_wrapper(WASMModuleInstance *module_inst)
{ {
WASMMemoryInstance *memory = module_inst->default_memory; WASMMemoryInstance *memory = module_inst->default_memory;

View File

@ -1,7 +1,7 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved. # Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309L) add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE)
set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}) set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})

View File

@ -0,0 +1,14 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE)
set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${PLATFORM_LIB_DIR})
include_directories(${PLATFORM_LIB_DIR}/../include)
file (GLOB_RECURSE source_all ${PLATFORM_LIB_DIR}/*.c)
set (WASM_PLATFORM_LIB_SOURCE ${source_all})

View File

@ -37,7 +37,7 @@ wasm_hash_map_create(uint32 size, bool use_lock,
ValueDestroyFunc value_destroy_func) ValueDestroyFunc value_destroy_func)
{ {
HashMap *map; HashMap *map;
uint32 total_size; uint64 total_size;
if (size > HASH_MAP_MAX_SIZE) { if (size > HASH_MAP_MAX_SIZE) {
LOG_ERROR("HashMap create failed: size is too large.\n"); LOG_ERROR("HashMap create failed: size is too large.\n");
@ -51,19 +51,21 @@ wasm_hash_map_create(uint32 size, bool use_lock,
} }
total_size = offsetof(HashMap, elements) + total_size = offsetof(HashMap, elements) +
sizeof(HashMapElem) * size + sizeof(HashMapElem) * (uint64)size +
(use_lock ? sizeof(korp_mutex) : 0); (use_lock ? sizeof(korp_mutex) : 0);
if (!(map = wasm_malloc(total_size))) { if (total_size >= UINT32_MAX
|| !(map = wasm_malloc((uint32)total_size))) {
LOG_ERROR("HashMap create failed: alloc memory failed.\n"); LOG_ERROR("HashMap create failed: alloc memory failed.\n");
return NULL; return NULL;
} }
memset(map, 0, total_size); memset(map, 0, (uint32)total_size);
if (use_lock) { if (use_lock) {
map->lock = (korp_mutex*) map->lock = (korp_mutex*)
((uint8*)map + offsetof(HashMap, elements) + sizeof(HashMapElem) * size); ((uint8*)map + offsetof(HashMap, elements)
+ sizeof(HashMapElem) * size);
if (ws_mutex_init(map->lock, false)) { if (ws_mutex_init(map->lock, false)) {
LOG_ERROR("HashMap create failed: init map lock failed.\n"); LOG_ERROR("HashMap create failed: init map lock failed.\n");
wasm_free(map); wasm_free(map);

View File

@ -217,6 +217,19 @@ typedef struct BlockAddr {
#define BLOCK_ADDR_CACHE_SIZE 64 #define BLOCK_ADDR_CACHE_SIZE 64
#define BLOCK_ADDR_CONFLICT_SIZE 4 #define BLOCK_ADDR_CONFLICT_SIZE 4
#if WASM_ENABLE_WASI != 0
typedef struct WASIArguments {
const char **dir_list;
uint32 dir_count;
const char **map_dir_list;
uint32 map_dir_count;
const char **env;
uint32 env_count;
const char **argv;
uint32 argc;
} WASIArguments;
#endif
typedef struct WASMModule { typedef struct WASMModule {
uint32 type_count; uint32 type_count;
uint32 import_count; uint32 import_count;
@ -255,16 +268,19 @@ typedef struct WASMModule {
#else #else
BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE]; BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
#endif #endif
#if WASM_ENABLE_WASI != 0
WASIArguments wasi_args;
bool is_wasi_module;
#endif
} WASMModule; } WASMModule;
typedef struct WASMBranchBlock { typedef struct WASMBranchBlock {
uint8 block_type; uint8 block_type;
uint8 return_type; uint8 return_type;
uint8 *start_addr; uint8 *start_addr;
uint8 *else_addr;
uint8 *end_addr; uint8 *end_addr;
uint32 *frame_sp; uint32 *frame_sp;
uint8 *frame_ref;
} WASMBranchBlock; } WASMBranchBlock;
typedef struct WASMSection { typedef struct WASMSection {
@ -299,7 +315,7 @@ align_uint (unsigned v, unsigned b)
inline static uint32 inline static uint32
wasm_string_hash(const char *str) wasm_string_hash(const char *str)
{ {
unsigned h = strlen(str); unsigned h = (unsigned)strlen(str);
const uint8 *p = (uint8*)str; const uint8 *p = (uint8*)str;
const uint8 *end = p + h; const uint8 *end = p + h;
@ -356,11 +372,11 @@ wasm_value_type_cell_num(uint8 value_type)
inline static uint16 inline static uint16
wasm_get_cell_num(const uint8 *types, uint32 type_count) wasm_get_cell_num(const uint8 *types, uint32 type_count)
{ {
uint16 cell_num = 0; uint32 cell_num = 0;
uint32 i; uint32 i;
for (i = 0; i < type_count; i++) for (i = 0; i < type_count; i++)
cell_num += wasm_value_type_cell_num(types[i]); cell_num += wasm_value_type_cell_num(types[i]);
return cell_num; return (uint16)cell_num;
} }
inline static uint16 inline static uint16

View File

@ -15,6 +15,7 @@
#include "wasm_log.h" #include "wasm_log.h"
#include "wasm_memory.h" #include "wasm_memory.h"
#include "wasm_platform_log.h" #include "wasm_platform_log.h"
#include "bh_common.h"
static WASMFunctionInstance* static WASMFunctionInstance*
@ -55,17 +56,55 @@ check_main_func_type(const WASMType *type)
return true; return true;
} }
#if WASM_ENABLE_WASI != 0
static WASMFunctionInstance *
lookup_wasi_start_function(WASMModuleInstance *module_inst)
{
WASMFunctionInstance *func = NULL;
uint32 i;
for (i = 0; i < module_inst->export_func_count; i++) {
if (!strcmp(module_inst->export_functions[i].name, "_start")) {
func = module_inst->export_functions[i].function;
if (func->u.func->func_type->param_count != 0
|| func->u.func->func_type->result_count != 0) {
LOG_ERROR("Lookup wasi _start function failed: "
"invalid function type.\n");
return NULL;
}
return func;
}
}
return NULL;
}
#endif
bool bool
wasm_application_execute_main(WASMModuleInstance *module_inst, wasm_application_execute_main(WASMModuleInstance *module_inst,
int argc, char *argv[]) int argc, char *argv[])
{ {
WASMFunctionInstance *func = resolve_main_function(module_inst); WASMFunctionInstance *func;
uint32 argc1 = 0, argv1[2] = { 0 }; uint32 argc1 = 0, argv1[2] = { 0 };
uint32 total_argv_size = 0, total_size; uint32 total_argv_size = 0;
uint64 total_size;
int32 argv_buf_offset, i; int32 argv_buf_offset, i;
char *argv_buf, *p; char *argv_buf, *p, *p_end;
int32 *argv_offsets; int32 *argv_offsets;
#if WASM_ENABLE_WASI != 0
if (module_inst->module->is_wasi_module) {
/* In wasi mode, we should call function named "_start"
which initializes the wasi envrionment and then calls
the actual main function. Directly call main function
may cause exception thrown. */
if ((func = lookup_wasi_start_function(module_inst)))
return wasm_runtime_call_wasm(module_inst, NULL,
func, 0, NULL);
/* if no start function is found, we execute
the main function as normal */
}
#endif
func = resolve_main_function(module_inst);
if (!func || func->is_import_func) if (!func || func->is_import_func)
return false; return false;
@ -74,25 +113,28 @@ wasm_application_execute_main(WASMModuleInstance *module_inst,
if (func->u.func->func_type->param_count) { if (func->u.func->func_type->param_count) {
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
total_argv_size += strlen(argv[i]) + 1; total_argv_size += (uint32)(strlen(argv[i]) + 1);
total_argv_size = align_uint(total_argv_size, 4); total_argv_size = align_uint(total_argv_size, 4);
total_size = total_argv_size + sizeof(int32) * argc; total_size = (uint64)total_argv_size + sizeof(int32) * (uint64)argc;
if (!(argv_buf_offset = wasm_runtime_module_malloc(module_inst, total_size))) if (total_size >= UINT32_MAX
|| !(argv_buf_offset =
wasm_runtime_module_malloc(module_inst, (uint32)total_size)))
return false; return false;
argv_buf = p = wasm_runtime_addr_app_to_native(module_inst, argv_buf_offset); argv_buf = p = wasm_runtime_addr_app_to_native(module_inst, argv_buf_offset);
argv_offsets = (int32*)(p + total_argv_size); argv_offsets = (int32*)(p + total_argv_size);
p_end = p + total_size;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
memcpy(p, argv[i], strlen(argv[i]) + 1); bh_memcpy_s(p, (uint32)(p_end - p), argv[i], (uint32)(strlen(argv[i]) + 1));
argv_offsets[i] = argv_buf_offset + (p - argv_buf); argv_offsets[i] = argv_buf_offset + (int32)(p - argv_buf);
p += strlen(argv[i]) + 1; p += strlen(argv[i]) + 1;
} }
argc1 = 2; argc1 = 2;
argv1[0] = argc; argv1[0] = (uint32)argc;
argv1[1] = (uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets); argv1[1] = (uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
} }
@ -165,6 +207,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
WASMType *type; WASMType *type;
uint32 argc1, *argv1; uint32 argc1, *argv1;
int32 i, p; int32 i, p;
uint64 total_size;
const char *exception; const char *exception;
wasm_assert(argc >= 0); wasm_assert(argc >= 0);
@ -181,15 +224,16 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
} }
argc1 = func->param_cell_num; argc1 = func->param_cell_num;
argv1 = wasm_malloc(sizeof(uint32) * (argc1 > 2 ? argc1 : 2)); total_size = sizeof(uint32) * (uint64)(argc1 > 2 ? argc1 : 2);
if (argv1 == NULL) { if (total_size >= UINT32_MAX
|| (!(argv1 = wasm_malloc((uint32)total_size)))) {
LOG_ERROR("Wasm prepare param failed: malloc failed.\n"); LOG_ERROR("Wasm prepare param failed: malloc failed.\n");
return false; return false;
} }
/* Parse arguments */ /* Parse arguments */
for (i = 0, p = 0; i < argc; i++) { for (i = 0, p = 0; i < argc; i++) {
char *endptr; char *endptr = NULL;
wasm_assert(argv[i] != NULL); wasm_assert(argv[i] != NULL);
if (argv[i][0] == '\0') { if (argv[i][0] == '\0') {
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]); LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
@ -197,7 +241,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
} }
switch (type->types[i]) { switch (type->types[i]) {
case VALUE_TYPE_I32: case VALUE_TYPE_I32:
argv1[p++] = strtoul(argv[i], &endptr, 0); argv1[p++] = (uint32)strtoul(argv[i], &endptr, 0);
break; break;
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
{ {
@ -217,7 +261,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
if (endptr[0] == ':') { if (endptr[0] == ':') {
uint32 sig; uint32 sig;
union ieee754_float u; union ieee754_float u;
sig = strtoul(endptr + 1, &endptr, 0); sig = (uint32)strtoul(endptr + 1, &endptr, 0);
u.f = f32; u.f = f32;
if (is_little_endian()) if (is_little_endian())
u.ieee.ieee_little_endian.mantissa = sig; u.ieee.ieee_little_endian.mantissa = sig;
@ -244,11 +288,11 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
ud.d = u.val; ud.d = u.val;
if (is_little_endian()) { if (is_little_endian()) {
ud.ieee.ieee_little_endian.mantissa0 = sig >> 32; ud.ieee.ieee_little_endian.mantissa0 = sig >> 32;
ud.ieee.ieee_little_endian.mantissa1 = sig; ud.ieee.ieee_little_endian.mantissa1 = (uint32)sig;
} }
else { else {
ud.ieee.ieee_big_endian.mantissa0 = sig >> 32; ud.ieee.ieee_big_endian.mantissa0 = sig >> 32;
ud.ieee.ieee_big_endian.mantissa1 = sig; ud.ieee.ieee_big_endian.mantissa1 = (uint32)sig;
} }
u.val = ud.d; u.val = ud.d;
} }
@ -258,7 +302,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
break; break;
} }
} }
if (*endptr != '\0' && *endptr != '_') { if (endptr && *endptr != '\0' && *endptr != '_') {
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]); LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
goto fail; goto fail;
} }

View File

@ -33,7 +33,7 @@ typedef float64 CellType_F64;
#else /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */ #else /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
#define PUT_I64_TO_ADDR(addr, value) do { \ #define PUT_I64_TO_ADDR(addr, value) do { \
union { int64 val; uint32 parts[2]; } u; \ union { int64 val; uint32 parts[2]; } u; \
u.val = (value); \ u.val = (int64)(value); \
(addr)[0] = u.parts[0]; \ (addr)[0] = u.parts[0]; \
(addr)[1] = u.parts[1]; \ (addr)[1] = u.parts[1]; \
} while (0) } while (0)
@ -110,36 +110,36 @@ GET_F64_FROM_ADDR (uint32 *addr)
} while (0) } while (0)
static inline uint32 static inline uint32
rotl32(uint32 n, unsigned int c) rotl32(uint32 n, uint32 c)
{ {
const unsigned int mask = (31); const uint32 mask = (31);
c = c % 32; c = c % 32;
c &= mask; c &= mask;
return (n<<c) | (n>>( (-c)&mask )); return (n<<c) | (n>>( (-c)&mask ));
} }
static inline uint32 static inline uint32
rotr32(uint32 n, unsigned int c) rotr32(uint32 n, uint32 c)
{ {
const unsigned int mask = (31); const uint32 mask = (31);
c = c % 32; c = c % 32;
c &= mask; c &= mask;
return (n>>c) | (n<<( (-c)&mask )); return (n>>c) | (n<<( (-c)&mask ));
} }
static inline uint64 static inline uint64
rotl64(uint64 n, unsigned int c) rotl64(uint64 n, uint64 c)
{ {
const unsigned int mask = (63); const uint64 mask = (63);
c = c % 64; c = c % 64;
c &= mask; c &= mask;
return (n<<c) | (n>>( (-c)&mask )); return (n<<c) | (n>>( (-c)&mask ));
} }
static inline uint64 static inline uint64
rotr64(uint64 n, unsigned int c) rotr64(uint64 n, uint64 c)
{ {
const unsigned int mask = (63); const uint64 mask = (63);
c = c % 64; c = c % 64;
c &= mask; c &= mask;
return (n>>c) | (n<<( (-c)&mask )); return (n>>c) | (n<<( (-c)&mask ));
@ -237,21 +237,6 @@ popcount64(uint64 u)
return ret; return ret;
} }
static inline WASMGlobalInstance*
get_global(const WASMModuleInstance *module, uint32 global_idx)
{
if (global_idx >= module->global_count)
return NULL;
return module->globals + global_idx;
}
static inline uint8*
get_global_addr(WASMMemoryInstance *memory, WASMGlobalInstance *global)
{
return memory->global_data + global->data_offset;
}
static uint64 static uint64
read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign) read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
{ {
@ -300,7 +285,6 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
frame_csp->block_type = type; \ frame_csp->block_type = type; \
frame_csp->return_type = ret_type; \ frame_csp->return_type = ret_type; \
frame_csp->start_addr = start; \ frame_csp->start_addr = start; \
frame_csp->else_addr = else_; \
frame_csp->end_addr = end; \ frame_csp->end_addr = end; \
frame_csp->frame_sp = frame_sp; \ frame_csp->frame_sp = frame_sp; \
frame_csp++; \ frame_csp++; \
@ -355,28 +339,28 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
#define LOCAL_I32(n) (*(int32*)(local_off(n))) #define LOCAL_I32(n) (*(int32*)(local_off(n)))
#define SET_LOCAL_I32(N, val) do { \ #define SET_LOCAL_I32(N, val) do { \
int n = (N); \ uint32 n = (N); \
*(int32*)(local_off(n)) = (int32)(val); \ *(int32*)(local_off(n)) = (int32)(val); \
} while (0) } while (0)
#define LOCAL_F32(n) (*(float32*)(local_off(n))) #define LOCAL_F32(n) (*(float32*)(local_off(n)))
#define SET_LOCAL_F32(N, val) do { \ #define SET_LOCAL_F32(N, val) do { \
int n = (N); \ uint32 n = (N); \
*(float32*)(local_off(n)) = (float32)(val); \ *(float32*)(local_off(n)) = (float32)(val); \
} while (0) } while (0)
#define LOCAL_I64(n) (GET_I64_FROM_ADDR(local_off(n))) #define LOCAL_I64(n) (GET_I64_FROM_ADDR(local_off(n)))
#define SET_LOCAL_I64(N, val) do { \ #define SET_LOCAL_I64(N, val) do { \
int n = (N); \ uint32 n = (N); \
PUT_I64_TO_ADDR(local_off(n), val); \ PUT_I64_TO_ADDR(local_off(n), val); \
} while (0) } while (0)
#define LOCAL_F64(n) (GET_F64_FROM_ADDR(local_off(n))) #define LOCAL_F64(n) (GET_F64_FROM_ADDR(local_off(n)))
#define SET_LOCAL_F64(N, val) do { \ #define SET_LOCAL_F64(N, val) do { \
int n = (N); \ uint32 n = (N); \
PUT_F64_TO_ADDR(local_off(n), val); \ PUT_F64_TO_ADDR(local_off(n), val); \
} while (0) } while (0)
@ -476,7 +460,7 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
} while (0) } while (0)
#define DEF_OP_EQZ(src_op_type) do { \ #define DEF_OP_EQZ(src_op_type) do { \
uint32 val; \ int32 val; \
val = POP_##src_op_type() == 0; \ val = POP_##src_op_type() == 0; \
PUSH_I32(val); \ PUSH_I32(val); \
} while (0) } while (0)
@ -484,16 +468,16 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
#define DEF_OP_CMP(src_type, src_op_type, cond) do { \ #define DEF_OP_CMP(src_type, src_op_type, cond) do { \
uint32 res; \ uint32 res; \
src_type val1, val2; \ src_type val1, val2; \
val2 = POP_##src_op_type(); \ val2 = (src_type)POP_##src_op_type(); \
val1 = POP_##src_op_type(); \ val1 = (src_type)POP_##src_op_type(); \
res = val1 cond val2; \ res = val1 cond val2; \
PUSH_I32(res); \ PUSH_I32(res); \
} while (0) } while (0)
#define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) do { \ #define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) do { \
src_type val1, val2; \ src_type val1, val2; \
val1 = POP_##src_op_type(); \ val1 = (src_type)POP_##src_op_type(); \
val2 = operation(val1); \ val2 = (src_type)operation(val1); \
PUSH_##src_op_type(val2); \ PUSH_##src_op_type(val2); \
} while (0) } while (0)
@ -531,22 +515,20 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
} while (0) } while (0)
#define GET_LOCAL_INDEX_AND_TYPE() do { \ #define GET_LOCAL_INDEX_AND_TYPE() do { \
param_count = cur_func->u.func->func_type->param_count; \ uint32 param_count = cur_func->param_count; \
local_count = cur_func->u.func->local_count; \
read_leb_uint32(frame_ip, frame_ip_end, local_idx); \ read_leb_uint32(frame_ip, frame_ip_end, local_idx); \
wasm_assert(local_idx < param_count + local_count); \ wasm_assert(local_idx < param_count + cur_func->local_count); \
if (local_idx < param_count) \ if (local_idx < param_count) \
local_type = cur_func->u.func->func_type->types[local_idx]; \ local_type = cur_func->param_types[local_idx]; \
else \ else \
local_type = \ local_type = cur_func->local_types[local_idx - param_count]; \
cur_func->u.func->local_types[local_idx - param_count]; \
} while (0) } while (0)
static inline int32 static inline int32
sign_ext_8_32(int8 val) sign_ext_8_32(int8 val)
{ {
if (val & 0x80) if (val & 0x80)
return val | 0xffffff00; return (int32)val | (int32)0xffffff00;
return val; return val;
} }
@ -554,7 +536,7 @@ static inline int32
sign_ext_16_32(int16 val) sign_ext_16_32(int16 val)
{ {
if (val & 0x8000) if (val & 0x8000)
return val | 0xffff0000; return (int32)val | (int32)0xffff0000;
return val; return val;
} }
@ -562,7 +544,7 @@ static inline int64
sign_ext_8_64(int8 val) sign_ext_8_64(int8 val)
{ {
if (val & 0x80) if (val & 0x80)
return val | 0xffffffffffffff00; return (int64)val | (int64)0xffffffffffffff00;
return val; return val;
} }
@ -570,15 +552,15 @@ static inline int64
sign_ext_16_64(int16 val) sign_ext_16_64(int16 val)
{ {
if (val & 0x8000) if (val & 0x8000)
return val | 0xffffffffffff0000; return (int64)val | (int64)0xffffffffffff0000;
return val; return val;
} }
static inline int64 static inline int64
sign_ext_32_64(int32 val) sign_ext_32_64(int32 val)
{ {
if (val & 0x80000000) if (val & (int32)0x80000000)
return val | 0xffffffff00000000; return (int64)val | (int64)0xffffffff00000000;
return val; return val;
} }
@ -674,10 +656,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
WASMMemoryInstance *memory = module->default_memory; WASMMemoryInstance *memory = module->default_memory;
uint32 memory_data_size = memory uint32 memory_data_size = memory
? NumBytesPerPage * memory->cur_page_count : 0; ? NumBytesPerPage * memory->cur_page_count : 0;
uint32 heap_base_offset = memory ? memory->heap_base_offset : 0; uint32 heap_base_offset = memory ? (uint32)memory->heap_base_offset : 0;
uint32 heap_data_size = memory uint32 heap_data_size = memory
? memory->heap_data_end - memory->heap_data : 0; ? (uint32)(memory->heap_data_end - memory->heap_data) : 0;
WASMTableInstance *table = module->default_table; WASMTableInstance *table = module->default_table;
WASMGlobalInstance *globals = module->globals;
uint8 *global_data = memory ? memory->global_data : NULL;
uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2; uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2;
WASMInterpFrame *frame = NULL; WASMInterpFrame *frame = NULL;
/* Points to this special opcode so as to jump to the /* Points to this special opcode so as to jump to the
@ -690,10 +674,10 @@ wasm_interp_call_func_bytecode(WASMThread *self,
uint8 opcode, block_ret_type; uint8 opcode, block_ret_type;
uint32 *depths = NULL; uint32 *depths = NULL;
uint32 depth_buf[BR_TABLE_TMP_BUF_LEN]; uint32 depth_buf[BR_TABLE_TMP_BUF_LEN];
uint32 i, depth, cond, count, fidx, tidx, frame_size = 0, all_cell_num = 0; uint32 i, depth, cond, count, fidx, tidx, frame_size = 0;
uint64 all_cell_num = 0;
int32 didx, val; int32 didx, val;
uint8 *else_addr, *end_addr; uint8 *else_addr, *end_addr, *maddr = NULL;
uint8 *maddr = NULL;
#if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_ENABLE_LABELS_AS_VALUES != 0
#define HANDLE_OPCODE(op) &&HANDLE_##op #define HANDLE_OPCODE(op) &&HANDLE_##op
@ -723,7 +707,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
HANDLE_OP_END (); HANDLE_OP_END ();
HANDLE_OP (WASM_OP_BLOCK): HANDLE_OP (WASM_OP_BLOCK):
read_leb_uint32(frame_ip, frame_ip_end, block_ret_type); read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
if (!wasm_loader_find_block_addr(module->module, if (!wasm_loader_find_block_addr(module->module,
frame_ip, frame_ip_end, frame_ip, frame_ip_end,
@ -738,7 +722,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
HANDLE_OP_END (); HANDLE_OP_END ();
HANDLE_OP (WASM_OP_LOOP): HANDLE_OP (WASM_OP_LOOP):
read_leb_uint32(frame_ip, frame_ip_end, block_ret_type); read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
if (!wasm_loader_find_block_addr(module->module, if (!wasm_loader_find_block_addr(module->module,
frame_ip, frame_ip_end, frame_ip, frame_ip_end,
@ -753,7 +737,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
HANDLE_OP_END (); HANDLE_OP_END ();
HANDLE_OP (WASM_OP_IF): HANDLE_OP (WASM_OP_IF):
read_leb_uint32(frame_ip, frame_ip_end, block_ret_type); read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
if (!wasm_loader_find_block_addr(module->module, if (!wasm_loader_find_block_addr(module->module,
frame_ip, frame_ip_end, frame_ip, frame_ip_end,
@ -764,7 +748,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
goto got_exception; goto got_exception;
} }
cond = POP_I32(); cond = (uint32)POP_I32();
PUSH_CSP(BLOCK_TYPE_IF, block_ret_type, frame_ip, else_addr, end_addr); PUSH_CSP(BLOCK_TYPE_IF, block_ret_type, frame_ip, else_addr, end_addr);
@ -806,7 +790,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
HANDLE_OP (WASM_OP_BR_IF): HANDLE_OP (WASM_OP_BR_IF):
read_leb_uint32(frame_ip, frame_ip_end, depth); read_leb_uint32(frame_ip, frame_ip_end, depth);
cond = POP_I32(); cond = (uint32)POP_I32();
if (cond) if (cond)
POP_CSP_N(depth); POP_CSP_N(depth);
HANDLE_OP_END (); HANDLE_OP_END ();
@ -816,7 +800,9 @@ wasm_interp_call_func_bytecode(WASMThread *self,
if (count <= BR_TABLE_TMP_BUF_LEN) if (count <= BR_TABLE_TMP_BUF_LEN)
depths = depth_buf; depths = depth_buf;
else { else {
if (!(depths = wasm_malloc(sizeof(uint32) * count))) { uint64 total_size = sizeof(uint32) * (uint64)count;
if (total_size >= UINT32_MAX
|| !(depths = wasm_malloc((uint32)total_size))) {
wasm_runtime_set_exception(module, wasm_runtime_set_exception(module,
"WASM interp failed: " "WASM interp failed: "
"allocate memory failed."); "allocate memory failed.");
@ -916,7 +902,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
HANDLE_OP (WASM_OP_SELECT_32): HANDLE_OP (WASM_OP_SELECT_32):
{ {
cond = POP_I32(); cond = (uint32)POP_I32();
frame_sp--; frame_sp--;
if (!cond) if (!cond)
*(frame_sp - 1) = *frame_sp; *(frame_sp - 1) = *frame_sp;
@ -925,7 +911,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
HANDLE_OP (WASM_OP_SELECT_64): HANDLE_OP (WASM_OP_SELECT_64):
{ {
cond = POP_I32(); cond = (uint32)POP_I32();
frame_sp -= 2; frame_sp -= 2;
if (!cond) { if (!cond) {
*(frame_sp - 2) = *frame_sp; *(frame_sp - 2) = *frame_sp;
@ -937,7 +923,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
/* variable instructions */ /* variable instructions */
HANDLE_OP (WASM_OP_GET_LOCAL): HANDLE_OP (WASM_OP_GET_LOCAL):
{ {
uint32 local_idx, param_count, local_count; uint32 local_idx;
uint8 local_type; uint8 local_type;
GET_LOCAL_INDEX_AND_TYPE(); GET_LOCAL_INDEX_AND_TYPE();
@ -960,13 +946,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
"invalid local type"); "invalid local type");
goto got_exception; goto got_exception;
} }
(void)local_count;
HANDLE_OP_END (); HANDLE_OP_END ();
} }
HANDLE_OP (WASM_OP_SET_LOCAL): HANDLE_OP (WASM_OP_SET_LOCAL):
{ {
uint32 local_idx, param_count, local_count; uint32 local_idx;
uint8 local_type; uint8 local_type;
GET_LOCAL_INDEX_AND_TYPE(); GET_LOCAL_INDEX_AND_TYPE();
@ -989,13 +974,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
"invalid local type"); "invalid local type");
goto got_exception; goto got_exception;
} }
(void)local_count;
HANDLE_OP_END (); HANDLE_OP_END ();
} }
HANDLE_OP (WASM_OP_TEE_LOCAL): HANDLE_OP (WASM_OP_TEE_LOCAL):
{ {
uint32 local_idx, param_count, local_count; uint32 local_idx;
uint8 local_type; uint8 local_type;
GET_LOCAL_INDEX_AND_TYPE(); GET_LOCAL_INDEX_AND_TYPE();
@ -1017,7 +1001,6 @@ wasm_interp_call_func_bytecode(WASMThread *self,
wasm_runtime_set_exception(module, "invalid local type"); wasm_runtime_set_exception(module, "invalid local type");
goto got_exception; goto got_exception;
} }
(void)local_count;
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -1025,24 +1008,26 @@ wasm_interp_call_func_bytecode(WASMThread *self,
{ {
WASMGlobalInstance *global; WASMGlobalInstance *global;
uint32 global_idx; uint32 global_idx;
uint8 *global_addr;
read_leb_uint32(frame_ip, frame_ip_end, global_idx); read_leb_uint32(frame_ip, frame_ip_end, global_idx);
global = get_global(module, global_idx); wasm_assert(global_idx < module->global_count);
wasm_assert(global && global_idx < module->global_count); global = globals + global_idx;
global_addr = global_data + global->data_offset;
switch (global->type) { switch (global->type) {
case VALUE_TYPE_I32: case VALUE_TYPE_I32:
PUSH_I32(*(uint32*)get_global_addr(memory, global)); PUSH_I32(*(uint32*)global_addr);
break; break;
case VALUE_TYPE_F32: case VALUE_TYPE_F32:
PUSH_F32(*(float32*)get_global_addr(memory, global)); PUSH_F32(*(float32*)global_addr);
break; break;
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
PUSH_I64(*(uint64*)get_global_addr(memory, global)); PUSH_I64(GET_I64_FROM_ADDR((uint32*)global_addr));
break; break;
case VALUE_TYPE_F64: case VALUE_TYPE_F64:
PUSH_F64(*(float64*)get_global_addr(memory, global)); PUSH_F64(GET_F64_FROM_ADDR((uint32*)global_addr));
break; break;
default: default:
wasm_runtime_set_exception(module, "invalid global type"); wasm_runtime_set_exception(module, "invalid global type");
@ -1059,13 +1044,13 @@ wasm_interp_call_func_bytecode(WASMThread *self,
read_leb_uint32(frame_ip, frame_ip_end, global_idx); read_leb_uint32(frame_ip, frame_ip_end, global_idx);
global = get_global(module, global_idx); wasm_assert(global_idx < module->global_count);
wasm_assert(global && global_idx < module->global_count); global = globals + global_idx;
global_addr = global_data + global->data_offset;
global_addr = get_global_addr(memory, global);
switch (global->type) { switch (global->type) {
case VALUE_TYPE_I32: case VALUE_TYPE_I32:
*(uint32*)global_addr = POP_I32(); *(int32*)global_addr = POP_I32();
break; break;
case VALUE_TYPE_F32: case VALUE_TYPE_F32:
*(float32*)global_addr = POP_F32(); *(float32*)global_addr = POP_F32();
@ -1103,7 +1088,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
GET_OPCODE(); GET_OPCODE();
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset); read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32(); addr = (uint32)POP_I32();
CHECK_MEMORY_OVERFLOW(); CHECK_MEMORY_OVERFLOW();
#if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_ENABLE_LABELS_AS_VALUES != 0
static const void *handle_load_table[] = { static const void *handle_load_table[] = {
@ -1184,7 +1169,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset); read_leb_uint32(frame_ip, frame_ip_end, offset);
frame_sp--; frame_sp--;
addr = POP_I32(); addr = (uint32)POP_I32();
CHECK_MEMORY_OVERFLOW(); CHECK_MEMORY_OVERFLOW();
*(uint32*)maddr = frame_sp[1]; *(uint32*)maddr = frame_sp[1];
(void)flags; (void)flags;
@ -1198,7 +1183,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset); read_leb_uint32(frame_ip, frame_ip_end, offset);
frame_sp -= 2; frame_sp -= 2;
addr = POP_I32(); addr = (uint32)POP_I32();
CHECK_MEMORY_OVERFLOW(); CHECK_MEMORY_OVERFLOW();
*(uint32*)maddr = frame_sp[1]; *(uint32*)maddr = frame_sp[1];
*((uint32*)maddr + 1) = frame_sp[2]; *((uint32*)maddr + 1) = frame_sp[2];
@ -1215,12 +1200,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
GET_OPCODE(); GET_OPCODE();
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset); read_leb_uint32(frame_ip, frame_ip_end, offset);
sval = POP_I32(); sval = (uint32)POP_I32();
addr = POP_I32(); addr = (uint32)POP_I32();
CHECK_MEMORY_OVERFLOW(); CHECK_MEMORY_OVERFLOW();
switch (opcode) { switch (opcode) {
case WASM_OP_I32_STORE: case WASM_OP_I32_STORE:
*(int32*)maddr = sval; *(uint32*)maddr = sval;
break; break;
case WASM_OP_I32_STORE8: case WASM_OP_I32_STORE8:
*(uint8*)maddr = (uint8)sval; *(uint8*)maddr = (uint8)sval;
@ -1243,8 +1228,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
GET_OPCODE(); GET_OPCODE();
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset); read_leb_uint32(frame_ip, frame_ip_end, offset);
sval = POP_I64(); sval = (uint64)POP_I64();
addr = POP_I32(); addr = (uint32)POP_I32();
CHECK_MEMORY_OVERFLOW(); CHECK_MEMORY_OVERFLOW();
switch (opcode) { switch (opcode) {
case WASM_OP_I64_STORE: case WASM_OP_I64_STORE:
@ -1279,13 +1264,13 @@ wasm_interp_call_func_bytecode(WASMThread *self,
uint32 reserved, delta, prev_page_count = memory->cur_page_count; uint32 reserved, delta, prev_page_count = memory->cur_page_count;
read_leb_uint32(frame_ip, frame_ip_end, reserved); read_leb_uint32(frame_ip, frame_ip_end, reserved);
delta = POP_I32(); delta = (uint32)POP_I32();
if (!wasm_runtime_enlarge_memory(module, delta)) { if (!wasm_runtime_enlarge_memory(module, delta)) {
/* fail to memory.grow, return -1 */ /* fail to memory.grow, return -1 */
PUSH_I32(-1); PUSH_I32(-1);
if (wasm_runtime_get_exception(module)) { if (wasm_runtime_get_exception(module)) {
printf("%s\n", wasm_runtime_get_exception(module)); bh_printf("%s\n", wasm_runtime_get_exception(module));
wasm_runtime_set_exception(module, NULL); wasm_runtime_set_exception(module, NULL);
} }
} }
@ -1295,6 +1280,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
/* update the memory instance ptr */ /* update the memory instance ptr */
memory = module->default_memory; memory = module->default_memory;
memory_data_size = NumBytesPerPage * memory->cur_page_count; memory_data_size = NumBytesPerPage * memory->cur_page_count;
global_data = memory->global_data;
} }
(void)reserved; (void)reserved;
@ -1514,8 +1500,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
{ {
uint32 a, b; uint32 a, b;
b = POP_I32(); b = (uint32)POP_I32();
a = POP_I32(); a = (uint32)POP_I32();
if (b == 0) { if (b == 0) {
wasm_runtime_set_exception(module, "integer divide by zero"); wasm_runtime_set_exception(module, "integer divide by zero");
goto got_exception; goto got_exception;
@ -1546,8 +1532,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
{ {
uint32 a, b; uint32 a, b;
b = POP_I32(); b = (uint32)POP_I32();
a = POP_I32(); a = (uint32)POP_I32();
if (b == 0) { if (b == 0) {
wasm_runtime_set_exception(module, "integer divide by zero"); wasm_runtime_set_exception(module, "integer divide by zero");
goto got_exception; goto got_exception;
@ -1584,8 +1570,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
{ {
uint32 a, b; uint32 a, b;
b = POP_I32(); b = (uint32)POP_I32();
a = POP_I32(); a = (uint32)POP_I32();
PUSH_I32(rotl32(a, b)); PUSH_I32(rotl32(a, b));
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -1594,8 +1580,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
{ {
uint32 a, b; uint32 a, b;
b = POP_I32(); b = (uint32)POP_I32();
a = POP_I32(); a = (uint32)POP_I32();
PUSH_I32(rotr32(a, b)); PUSH_I32(rotr32(a, b));
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -1647,8 +1633,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
{ {
uint64 a, b; uint64 a, b;
b = POP_I64(); b = (uint64)POP_I64();
a = POP_I64(); a = (uint64)POP_I64();
if (b == 0) { if (b == 0) {
wasm_runtime_set_exception(module, "integer divide by zero"); wasm_runtime_set_exception(module, "integer divide by zero");
goto got_exception; goto got_exception;
@ -1679,8 +1665,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
{ {
uint64 a, b; uint64 a, b;
b = POP_I64(); b = (uint64)POP_I64();
a = POP_I64(); a = (uint64)POP_I64();
if (b == 0) { if (b == 0) {
wasm_runtime_set_exception(module, "integer divide by zero"); wasm_runtime_set_exception(module, "integer divide by zero");
goto got_exception; goto got_exception;
@ -1717,8 +1703,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
{ {
uint64 a, b; uint64 a, b;
b = POP_I64(); b = (uint64)POP_I64();
a = POP_I64(); a = (uint64)POP_I64();
PUSH_I64(rotl64(a, b)); PUSH_I64(rotl64(a, b));
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -1727,8 +1713,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
{ {
uint64 a, b; uint64 a, b;
b = POP_I64(); b = (uint64)POP_I64();
a = POP_I64(); a = (uint64)POP_I64();
PUSH_I64(rotr64(a, b)); PUSH_I64(rotr64(a, b));
HANDLE_OP_END (); HANDLE_OP_END ();
} }
@ -2092,14 +2078,23 @@ wasm_interp_call_func_bytecode(WASMThread *self,
goto got_exception; goto got_exception;
} }
else { else {
WASMFunction *cur_wasm_func = cur_func->u.func;
WASMType *func_type; WASMType *func_type;
uint8 ret_type; uint8 ret_type;
all_cell_num = cur_func->param_cell_num + cur_func->local_cell_num func_type = cur_wasm_func->func_type;
+ cur_func->u.func->max_stack_cell_num
+ cur_func->u.func->max_block_num * sizeof(WASMBranchBlock) / 4;
frame_size = wasm_interp_interp_frame_size(all_cell_num);
all_cell_num = (uint64)cur_func->param_cell_num
+ (uint64)cur_func->local_cell_num
+ (uint64)cur_wasm_func->max_stack_cell_num
+ ((uint64)cur_wasm_func->max_block_num) * sizeof(WASMBranchBlock) / 4;
if (all_cell_num >= UINT32_MAX) {
wasm_runtime_set_exception(self->module_inst,
"WASM interp failed: stack overflow.");
goto got_exception;
}
frame_size = wasm_interp_interp_frame_size((uint32)all_cell_num);
if (!(frame = ALLOC_FRAME(self, frame_size, prev_frame))) { if (!(frame = ALLOC_FRAME(self, frame_size, prev_frame))) {
frame = prev_frame; frame = prev_frame;
goto got_exception; goto got_exception;
@ -2113,19 +2108,18 @@ wasm_interp_call_func_bytecode(WASMThread *self,
frame_sp = frame->sp_bottom = frame_lp + cur_func->param_cell_num frame_sp = frame->sp_bottom = frame_lp + cur_func->param_cell_num
+ cur_func->local_cell_num; + cur_func->local_cell_num;
frame->sp_boundary = frame->sp_bottom + cur_func->u.func->max_stack_cell_num; frame->sp_boundary = frame->sp_bottom + cur_wasm_func->max_stack_cell_num;
frame_csp = frame->csp_bottom = (WASMBranchBlock*)frame->sp_boundary; frame_csp = frame->csp_bottom = (WASMBranchBlock*)frame->sp_boundary;
frame->csp_boundary = frame->csp_bottom + cur_func->u.func->max_block_num; frame->csp_boundary = frame->csp_bottom + cur_wasm_func->max_block_num;
/* Initialize the local varialbes */ /* Initialize the local varialbes */
memset(frame_lp + cur_func->param_cell_num, 0, memset(frame_lp + cur_func->param_cell_num, 0,
cur_func->local_cell_num * 4); (uint32)(cur_func->local_cell_num * 4));
/* Push function block as first block */ /* Push function block as first block */
func_type = cur_func->u.func->func_type;
ret_type = func_type->result_count ret_type = func_type->result_count
? func_type->types[func_type->param_count] ? cur_func->param_types[func_type->param_count]
: VALUE_TYPE_VOID; : VALUE_TYPE_VOID;
PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type, PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type,
frame_ip, NULL, frame_ip_end - 1); frame_ip, NULL, frame_ip_end - 1);

View File

@ -55,7 +55,8 @@ typedef struct WASMInterpFrame {
static inline unsigned static inline unsigned
wasm_interp_interp_frame_size(unsigned all_cell_num) wasm_interp_interp_frame_size(unsigned all_cell_num)
{ {
return align_uint(offsetof(WASMInterpFrame, lp) + all_cell_num * 5, 4); return align_uint((uint32)offsetof(WASMInterpFrame, lp)
+ all_cell_num * 5, 4);
} }
void void

View File

@ -11,6 +11,7 @@
#include "wasm_log.h" #include "wasm_log.h"
#include "wasm_memory.h" #include "wasm_memory.h"
#include "wasm_dlfcn.h" #include "wasm_dlfcn.h"
#include "bh_common.h"
/* Read a value of given type from the address pointed to by the given /* Read a value of given type from the address pointed to by the given
pointer and increase the pointer to the position just after the pointer and increase the pointer to the position just after the
@ -108,7 +109,7 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
error_buf, error_buf_size)) \ error_buf, error_buf_size)) \
return false; \ return false; \
p += off; \ p += off; \
res = (uint32)res64; \ res = (int32)res64; \
} while (0) } while (0)
#define read_leb_uint8(p, p_end, res) do { \ #define read_leb_uint8(p, p_end, res) do { \
@ -118,11 +119,11 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
error_buf, error_buf_size)) \ error_buf, error_buf_size)) \
return false; \ return false; \
p += off; \ p += off; \
res = (uint32)res64; \ res = (uint8)res64; \
} while (0) } while (0)
static char* static char*
const_str_set_insert(const uint8 *str, int32 len, WASMModule *module, const_str_set_insert(const uint8 *str, uint32 len, WASMModule *module,
char* error_buf, uint32 error_buf_size) char* error_buf, uint32 error_buf_size)
{ {
HashMap *set = module->const_str_set; HashMap *set = module->const_str_set;
@ -135,7 +136,7 @@ const_str_set_insert(const uint8 *str, int32 len, WASMModule *module,
return NULL; return NULL;
} }
memcpy(c_str, str, len); bh_memcpy_s(c_str, len + 1, str, len);
c_str[len] = '\0'; c_str[len] = '\0';
if ((value = wasm_hash_map_find(set, c_str))) { if ((value = wasm_hash_map_find(set, c_str))) {
@ -215,6 +216,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
{ {
const uint8 *p = buf, *p_end = buf_end, *p_org; const uint8 *p = buf, *p_end = buf_end, *p_org;
uint32 type_count, param_count, result_count, i, j; uint32 type_count, param_count, result_count, i, j;
uint64 total_size;
uint8 flag; uint8 flag;
WASMType *type; WASMType *type;
@ -222,13 +224,15 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
if (type_count) { if (type_count) {
module->type_count = type_count; module->type_count = type_count;
if (!(module->types = wasm_malloc(sizeof(WASMType*) * type_count))) { total_size = sizeof(WASMType*) * (uint64)type_count;
if (total_size >= UINT32_MAX
|| !(module->types = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load type section failed: allocate memory failed."); "Load type section failed: allocate memory failed.");
return false; return false;
} }
memset(module->types, 0, sizeof(WASMType*) * type_count); memset(module->types, 0, (uint32)total_size);
for (i = 0; i < type_count; i++) { for (i = 0; i < type_count; i++) {
CHECK_BUF(p, p_end, 1); CHECK_BUF(p, p_end, 1);
@ -254,8 +258,10 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
CHECK_BUF(p, p_end, result_count); CHECK_BUF(p, p_end, result_count);
p = p_org; p = p_org;
if (!(type = module->types[i] = wasm_malloc(offsetof(WASMType, types) + total_size = offsetof(WASMType, types) +
sizeof(uint8) * (param_count + result_count)))) { sizeof(uint8) * (uint64)(param_count + result_count);
if (total_size >= UINT32_MAX
|| !(type = module->types[i] = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load type section failed: allocate memory failed."); "Load type section failed: allocate memory failed.");
return false; return false;
@ -398,6 +404,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
{ {
const uint8 *p = buf, *p_end = buf_end, *p_old; const uint8 *p = buf, *p_end = buf_end, *p_old;
uint32 import_count, name_len, type_index, i, u32, flags; uint32 import_count, name_len, type_index, i, u32, flags;
uint64 total_size;
WASMImport *import; WASMImport *import;
WASMImport *import_functions = NULL, *import_tables = NULL; WASMImport *import_functions = NULL, *import_tables = NULL;
WASMImport *import_memories = NULL, *import_globals = NULL; WASMImport *import_memories = NULL, *import_globals = NULL;
@ -408,13 +415,15 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
if (import_count) { if (import_count) {
module->import_count = import_count; module->import_count = import_count;
if (!(module->imports = wasm_malloc(sizeof(WASMImport) * import_count))) { total_size = sizeof(WASMImport) * (uint64)import_count;
if (total_size >= UINT32_MAX
|| !(module->imports = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load import section failed: allocate memory failed."); "Load import section failed: allocate memory failed.");
return false; return false;
} }
memset(module->imports, 0, sizeof(WASMImport) * import_count); memset(module->imports, 0, (uint32)total_size);
p_old = p; p_old = p;
@ -514,6 +523,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
read_leb_uint8(p, p_end, kind); read_leb_uint8(p, p_end, kind);
switch (kind) { switch (kind) {
case IMPORT_KIND_FUNC: /* import function */ case IMPORT_KIND_FUNC: /* import function */
wasm_assert(import_functions);
import = import_functions++; import = import_functions++;
read_leb_uint32(p, p_end, type_index); read_leb_uint32(p, p_end, type_index);
if (type_index >= module->type_count) { if (type_index >= module->type_count) {
@ -543,6 +553,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
break; break;
case IMPORT_KIND_TABLE: /* import table */ case IMPORT_KIND_TABLE: /* import table */
wasm_assert(import_tables);
import = import_tables++; import = import_tables++;
if (!load_table_import(&p, p_end, &import->u.table, if (!load_table_import(&p, p_end, &import->u.table,
error_buf, error_buf_size)) error_buf, error_buf_size))
@ -554,6 +565,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
break; break;
case IMPORT_KIND_MEMORY: /* import memory */ case IMPORT_KIND_MEMORY: /* import memory */
wasm_assert(import_memories);
import = import_memories++; import = import_memories++;
if (!load_memory_import(&p, p_end, &import->u.memory, if (!load_memory_import(&p, p_end, &import->u.memory,
error_buf, error_buf_size)) error_buf, error_buf_size))
@ -565,6 +577,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
break; break;
case IMPORT_KIND_GLOBAL: /* import global */ case IMPORT_KIND_GLOBAL: /* import global */
wasm_assert(import_globals);
import = import_globals++; import = import_globals++;
read_leb_uint8(p, p_end, import->u.global.type); read_leb_uint8(p, p_end, import->u.global.type);
read_leb_uint8(p, p_end, mutable); read_leb_uint8(p, p_end, mutable);
@ -590,6 +603,16 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
import->u.names.module_name = module_name; import->u.names.module_name = module_name;
import->u.names.field_name = field_name; import->u.names.field_name = field_name;
} }
#if WASM_ENABLE_WASI != 0
import = module->import_functions;
for (i = 0; i < module->import_function_count; i++, import++) {
if (!strcmp(import->u.names.module_name, "wasi_unstable")) {
module->is_wasi_module = true;
break;
}
}
#endif
} }
if (p != p_end) { if (p != p_end) {
@ -613,7 +636,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
{ {
const uint8 *p = buf, *p_end = buf_end; const uint8 *p = buf, *p_end = buf_end;
const uint8 *p_code = buf_code, *p_code_end, *p_code_save; const uint8 *p_code = buf_code, *p_code_end, *p_code_save;
uint32 func_count, total_size; uint32 func_count;
uint64 total_size;
uint32 code_count = 0, code_size, type_index, i, j, k, local_type_index; uint32 code_count = 0, code_size, type_index, i, j, k, local_type_index;
uint32 local_count, local_set_count, sub_local_count; uint32 local_count, local_set_count, sub_local_count;
uint8 type; uint8 type;
@ -632,13 +656,15 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
if (func_count) { if (func_count) {
module->function_count = func_count; module->function_count = func_count;
if (!(module->functions = wasm_malloc(sizeof(WASMFunction*) * func_count))) { total_size = sizeof(WASMFunction*) * (uint64)func_count;
if (total_size >= UINT32_MAX
|| !(module->functions = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load function section failed: allocate memory failed."); "Load function section failed: allocate memory failed.");
return false; return false;
} }
memset(module->functions, 0, sizeof(WASMFunction*) * func_count); memset(module->functions, 0, (uint32)total_size);
for (i = 0; i < func_count; i++) { for (i = 0; i < func_count; i++) {
/* Resolve function type */ /* Resolve function type */
@ -678,10 +704,11 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
} }
/* Alloc memory, layout: function structure + local types */ /* Alloc memory, layout: function structure + local types */
code_size = p_code_end - p_code; code_size = (uint32)(p_code_end - p_code);
total_size = sizeof(WASMFunction) + local_count;
if (!(func = module->functions[i] = wasm_malloc(total_size))) { total_size = sizeof(WASMFunction) + (uint64)local_count;
if (total_size >= UINT32_MAX
|| !(func = module->functions[i] = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load function section failed: " "Load function section failed: "
"allocate memory failed."); "allocate memory failed.");
@ -689,7 +716,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
} }
/* Set function type, local count, code size and code body */ /* Set function type, local count, code size and code body */
memset(func, 0, total_size); memset(func, 0, (uint32)total_size);
func->func_type = module->types[type_index]; func->func_type = module->types[type_index];
func->local_count = local_count; func->local_count = local_count;
if (local_count > 0) if (local_count > 0)
@ -741,6 +768,7 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
{ {
const uint8 *p = buf, *p_end = buf_end; const uint8 *p = buf, *p_end = buf_end;
uint32 table_count, i; uint32 table_count, i;
uint64 total_size;
WASMTable *table; WASMTable *table;
read_leb_uint32(p, p_end, table_count); read_leb_uint32(p, p_end, table_count);
@ -752,14 +780,16 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
return false; return false;
} }
module->table_count = table_count; module->table_count = table_count;
if (!(module->tables = wasm_malloc(sizeof(WASMTable) * table_count))) { total_size = sizeof(WASMTable) * (uint64)table_count;
if (total_size >= UINT32_MAX
|| !(module->tables = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load table section failed: " "Load table section failed: "
"allocate memory failed."); "allocate memory failed.");
return false; return false;
} }
memset(module->tables, 0, sizeof(WASMTable) * table_count); memset(module->tables, 0, (uint32)total_size);
/* load each table */ /* load each table */
table = module->tables; table = module->tables;
@ -784,6 +814,7 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
{ {
const uint8 *p = buf, *p_end = buf_end; const uint8 *p = buf, *p_end = buf_end;
uint32 memory_count, i; uint32 memory_count, i;
uint64 total_size;
WASMMemory *memory; WASMMemory *memory;
read_leb_uint32(p, p_end, memory_count); read_leb_uint32(p, p_end, memory_count);
@ -795,14 +826,16 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
return false; return false;
} }
module->memory_count = memory_count; module->memory_count = memory_count;
if (!(module->memories = wasm_malloc(sizeof(WASMMemory) * memory_count))) { total_size = sizeof(WASMMemory) * (uint64)memory_count;
if (total_size >= UINT32_MAX
|| !(module->memories = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load memory section failed: " "Load memory section failed: "
"allocate memory failed."); "allocate memory failed.");
return false; return false;
} }
memset(module->memories, 0, sizeof(WASMMemory) * memory_count); memset(module->memories, 0, (uint32)total_size);
/* load each memory */ /* load each memory */
memory = module->memories; memory = module->memories;
@ -827,20 +860,23 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
{ {
const uint8 *p = buf, *p_end = buf_end; const uint8 *p = buf, *p_end = buf_end;
uint32 global_count, i; uint32 global_count, i;
uint64 total_size;
WASMGlobal *global; WASMGlobal *global;
read_leb_uint32(p, p_end, global_count); read_leb_uint32(p, p_end, global_count);
if (global_count) { if (global_count) {
module->global_count = global_count; module->global_count = global_count;
if (!(module->globals = wasm_malloc(sizeof(WASMGlobal) * global_count))) { total_size = sizeof(WASMGlobal) * (uint64)global_count;
if (total_size >= UINT32_MAX
|| !(module->globals = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load global section failed: " "Load global section failed: "
"allocate memory failed."); "allocate memory failed.");
return false; return false;
} }
memset(module->globals, 0, sizeof(WASMGlobal) * global_count); memset(module->globals, 0, (uint32)total_size);
global = module->globals; global = module->globals;
@ -872,21 +908,24 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
{ {
const uint8 *p = buf, *p_end = buf_end; const uint8 *p = buf, *p_end = buf_end;
uint32 export_count, i, index; uint32 export_count, i, index;
uint8 str_len; uint64 total_size;
uint32 str_len;
WASMExport *export; WASMExport *export;
read_leb_uint32(p, p_end, export_count); read_leb_uint32(p, p_end, export_count);
if (export_count) { if (export_count) {
module->export_count = export_count; module->export_count = export_count;
if (!(module->exports = wasm_malloc(sizeof(WASMExport) * export_count))) { total_size = sizeof(WASMExport) * (uint64)export_count;
if (total_size >= UINT32_MAX
|| !(module->exports = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load export section failed: " "Load export section failed: "
"allocate memory failed."); "allocate memory failed.");
return false; return false;
} }
memset(module->exports, 0, sizeof(WASMExport) * export_count); memset(module->exports, 0, (uint32)total_size);
export = module->exports; export = module->exports;
for (i = 0; i < export_count; i++, export++) { for (i = 0; i < export_count; i++, export++) {
@ -965,21 +1004,23 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m
{ {
const uint8 *p = buf, *p_end = buf_end; const uint8 *p = buf, *p_end = buf_end;
uint32 table_segment_count, i, j, table_index, function_count, function_index; uint32 table_segment_count, i, j, table_index, function_count, function_index;
uint64 total_size;
WASMTableSeg *table_segment; WASMTableSeg *table_segment;
read_leb_uint32(p, p_end, table_segment_count); read_leb_uint32(p, p_end, table_segment_count);
if (table_segment_count) { if (table_segment_count) {
module->table_seg_count = table_segment_count; module->table_seg_count = table_segment_count;
if (!(module->table_segments = wasm_malloc total_size = sizeof(WASMTableSeg) * (uint64)table_segment_count;
(sizeof(WASMTableSeg) * table_segment_count))) { if (total_size >= UINT32_MAX
|| !(module->table_segments = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load table segment section failed: " "Load table segment section failed: "
"allocate memory failed."); "allocate memory failed.");
return false; return false;
} }
memset(module->table_segments, 0, sizeof(WASMTableSeg) * table_segment_count); memset(module->table_segments, 0, (uint32)total_size);
table_segment = module->table_segments; table_segment = module->table_segments;
for (i = 0; i < table_segment_count; i++, table_segment++) { for (i = 0; i < table_segment_count; i++, table_segment++) {
@ -993,8 +1034,10 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m
read_leb_uint32(p, p_end, function_count); read_leb_uint32(p, p_end, function_count);
table_segment->function_count = function_count; table_segment->function_count = function_count;
if (!(table_segment->func_indexes = (uint32 *) total_size = sizeof(uint32) * (uint64)function_count;
wasm_malloc(sizeof(uint32) * function_count))) { if (total_size >= UINT32_MAX
|| !(table_segment->func_indexes = (uint32 *)
wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load table segment section failed: " "Load table segment section failed: "
"allocate memory failed."); "allocate memory failed.");
@ -1025,6 +1068,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
{ {
const uint8 *p = buf, *p_end = buf_end; const uint8 *p = buf, *p_end = buf_end;
uint32 data_seg_count, i, mem_index, data_seg_len; uint32 data_seg_count, i, mem_index, data_seg_len;
uint64 total_size;
WASMDataSeg *dataseg; WASMDataSeg *dataseg;
InitializerExpression init_expr; InitializerExpression init_expr;
@ -1032,15 +1076,16 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
if (data_seg_count) { if (data_seg_count) {
module->data_seg_count = data_seg_count; module->data_seg_count = data_seg_count;
if (!(module->data_segments = total_size = sizeof(WASMDataSeg*) * (uint64)data_seg_count;
wasm_malloc(sizeof(WASMDataSeg*) * data_seg_count))) { if (total_size >= UINT32_MAX
|| !(module->data_segments = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load data segment section failed: " "Load data segment section failed: "
"allocate memory failed."); "allocate memory failed.");
return false; return false;
} }
memset(module->data_segments, 0, sizeof(WASMDataSeg*) * data_seg_count); memset(module->data_segments, 0, (uint32)total_size);
for (i = 0; i < data_seg_count; i++) { for (i = 0; i < data_seg_count; i++) {
read_leb_uint32(p, p_end, mem_index); read_leb_uint32(p, p_end, mem_index);
@ -1051,14 +1096,15 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
read_leb_uint32(p, p_end, data_seg_len); read_leb_uint32(p, p_end, data_seg_len);
if (!(dataseg = module->data_segments[i] = if (!(dataseg = module->data_segments[i] =
wasm_malloc(sizeof(WASMDataSeg)))) { wasm_malloc((uint32)sizeof(WASMDataSeg)))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Load data segment section failed: " "Load data segment section failed: "
"allocate memory failed."); "allocate memory failed.");
return false; return false;
} }
memcpy(&dataseg->base_offset, &init_expr, sizeof(init_expr)); bh_memcpy_s(&dataseg->base_offset, sizeof(InitializerExpression),
&init_expr, sizeof(InitializerExpression));
dataseg->memory_index = mem_index; dataseg->memory_index = mem_index;
dataseg->data_length = data_seg_len; dataseg->data_length = data_seg_len;
@ -1343,6 +1389,8 @@ create_sections(const uint8 *buf, uint32 size,
uint8 section_type; uint8 section_type;
uint32 section_size; uint32 section_size;
wasm_assert(!*p_section_list);
p += 8; p += 8;
while (p < p_end) { while (p < p_end) {
CHECK_BUF(p, p_end, 1); CHECK_BUF(p, p_end, 1);
@ -1548,6 +1596,25 @@ wasm_loader_unload(WASMModule *module)
wasm_free(module); wasm_free(module);
} }
#if WASM_ENABLE_WASI != 0
void
wasm_runtime_set_wasi_args(WASMModule *module,
const char *dir_list[], uint32 dir_count,
const char *map_dir_list[], uint32 map_dir_count,
const char *env_list[], uint32 env_count,
const char *argv[], uint32 argc)
{
module->wasi_args.dir_list = dir_list;
module->wasi_args.dir_count = dir_count;
module->wasi_args.map_dir_list = map_dir_list;
module->wasi_args.map_dir_count = map_dir_count;
module->wasi_args.env = env_list;
module->wasi_args.env_count = env_count;
module->wasi_args.argv = argv;
module->wasi_args.argc = argc;
}
#endif
#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 #if WASM_ENABLE_HASH_BLOCK_ADDR != 0
typedef struct block_addr { typedef struct block_addr {
uint8 block_type; uint8 block_type;
@ -1568,7 +1635,8 @@ wasm_loader_find_block_addr(WASMModule *module,
{ {
const uint8 *p = start_addr, *p_end = code_end_addr; const uint8 *p = start_addr, *p_end = code_end_addr;
uint8 *else_addr = NULL; uint8 *else_addr = NULL;
uint32 block_nested_depth = 1, count, i, u32, u64; uint32 block_nested_depth = 1, count, i, u32;
uint64 u64;
uint8 opcode, u8; uint8 opcode, u8;
#if WASM_ENABLE_HASH_BLOCK_ADDR != 0 #if WASM_ENABLE_HASH_BLOCK_ADDR != 0
@ -1586,7 +1654,7 @@ wasm_loader_find_block_addr(WASMModule *module,
BlockAddr block_stack[16] = { 0 }, *block; BlockAddr block_stack[16] = { 0 }, *block;
uint32 j, t; uint32 j, t;
i = ((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16); i = (uint32)(((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16));
i = i % BLOCK_ADDR_CACHE_SIZE; i = i % BLOCK_ADDR_CACHE_SIZE;
block = module->block_addr_cache[i]; block = module->block_addr_cache[i];
for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++) { for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++) {
@ -1613,7 +1681,7 @@ wasm_loader_find_block_addr(WASMModule *module,
case WASM_OP_BLOCK: case WASM_OP_BLOCK:
case WASM_OP_LOOP: case WASM_OP_LOOP:
case WASM_OP_IF: case WASM_OP_IF:
read_leb_uint32(p, p_end, u32); /* blocktype */ read_leb_uint8(p, p_end, u8); /* blocktype */
#if WASM_ENABLE_HASH_BLOCK_ADDR == 0 #if WASM_ENABLE_HASH_BLOCK_ADDR == 0
if (block_nested_depth < sizeof(block_stack)/sizeof(BlockAddr)) { if (block_nested_depth < sizeof(block_stack)/sizeof(BlockAddr)) {
block_stack[block_nested_depth].start_addr = p; block_stack[block_nested_depth].start_addr = p;
@ -1658,7 +1726,7 @@ wasm_loader_find_block_addr(WASMModule *module,
for (t = 0; t < sizeof(block_stack)/sizeof(BlockAddr); t++) { for (t = 0; t < sizeof(block_stack)/sizeof(BlockAddr); t++) {
start_addr = block_stack[t].start_addr; start_addr = block_stack[t].start_addr;
if (start_addr) { if (start_addr) {
i = ((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16); i = (uint32)(((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16));
i = i % BLOCK_ADDR_CACHE_SIZE; i = i % BLOCK_ADDR_CACHE_SIZE;
block = module->block_addr_cache[i]; block = module->block_addr_cache[i];
for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++) for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++)
@ -1937,7 +2005,7 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new)
uint8 *mem_new; uint8 *mem_new;
wasm_assert(size_new > size_old); wasm_assert(size_new > size_old);
if ((mem_new = wasm_malloc(size_new))) { if ((mem_new = wasm_malloc(size_new))) {
memcpy(mem_new, mem_old, size_old); bh_memcpy_s(mem_new, size_new, mem_old, size_old);
memset(mem_new + size_old, 0, size_new - size_old); memset(mem_new + size_old, 0, size_new - size_old);
wasm_free(mem_old); wasm_free(mem_old);
} }
@ -2171,8 +2239,9 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num,
#define CHECK_CSP_PUSH() do { \ #define CHECK_CSP_PUSH() do { \
if (frame_csp >= frame_csp_boundary) { \ if (frame_csp >= frame_csp_boundary) { \
MEM_REALLOC(frame_csp_bottom, frame_csp_size, \ MEM_REALLOC(frame_csp_bottom, frame_csp_size, \
frame_csp_size + 8 * sizeof(BranchBlock));\ (uint32)(frame_csp_size \
frame_csp_size += 8 * sizeof(BranchBlock); \ + 8 * sizeof(BranchBlock))); \
frame_csp_size += (uint32)(8 * sizeof(BranchBlock)); \
frame_csp_boundary = frame_csp_bottom + \ frame_csp_boundary = frame_csp_bottom + \
frame_csp_size / sizeof(BranchBlock); \ frame_csp_size / sizeof(BranchBlock); \
frame_csp = frame_csp_bottom + csp_num; \ frame_csp = frame_csp_bottom + csp_num; \
@ -2281,10 +2350,10 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
uint32 stack_cell_num = 0, csp_num = 0; uint32 stack_cell_num = 0, csp_num = 0;
uint32 frame_ref_size, frame_csp_size; uint32 frame_ref_size, frame_csp_size;
uint8 *param_types, ret_type, *local_types, local_type, global_type; uint8 *param_types, ret_type, *local_types, local_type, global_type;
uint32 count, i, local_idx, global_idx, block_return_type, depth, u32; uint32 count, i, local_idx, global_idx, depth, u32;
int32 i32, i32_const = 0; int32 i32, i32_const = 0;
int64 i64; int64 i64;
uint8 opcode, u8; uint8 opcode, u8, block_return_type;
bool return_value = false, is_i32_const = false; bool return_value = false, is_i32_const = false;
global_count = module->import_global_count + module->global_count; global_count = module->import_global_count + module->global_count;
@ -2332,18 +2401,18 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
break; break;
case WASM_OP_BLOCK: case WASM_OP_BLOCK:
read_leb_uint32(p, p_end, block_return_type); read_leb_uint8(p, p_end, block_return_type);
PUSH_CSP(BLOCK_TYPE_BLOCK, block_return_type, p); PUSH_CSP(BLOCK_TYPE_BLOCK, block_return_type, p);
break; break;
case WASM_OP_LOOP: case WASM_OP_LOOP:
read_leb_uint32(p, p_end, block_return_type); read_leb_uint8(p, p_end, block_return_type);
PUSH_CSP(BLOCK_TYPE_LOOP, block_return_type, p); PUSH_CSP(BLOCK_TYPE_LOOP, block_return_type, p);
break; break;
case WASM_OP_IF: case WASM_OP_IF:
POP_I32(); POP_I32();
read_leb_uint32(p, p_end, block_return_type); read_leb_uint8(p, p_end, block_return_type);
PUSH_CSP(BLOCK_TYPE_IF, block_return_type, p); PUSH_CSP(BLOCK_TYPE_IF, block_return_type, p);
if (!is_i32_const) if (!is_i32_const)
(frame_csp - 1)->jumped_by_br = true; (frame_csp - 1)->jumped_by_br = true;
@ -2535,8 +2604,10 @@ handle_op_br:
func_type = func_type =
module->functions[func_idx - module->import_function_count]->func_type; module->functions[func_idx - module->import_function_count]->func_type;
for (idx = func_type->param_count - 1; idx >= 0; idx--) if (func_type->param_count > 0) {
for (idx = (int32)(func_type->param_count - 1); idx >= 0; idx--)
POP_TYPE(func_type->types[idx]); POP_TYPE(func_type->types[idx]);
}
if (func_type->result_count) if (func_type->result_count)
PUSH_TYPE(func_type->types[func_type->param_count]); PUSH_TYPE(func_type->types[func_type->param_count]);
@ -2575,8 +2646,10 @@ handle_op_br:
func_type = module->types[type_idx]; func_type = module->types[type_idx];
for (idx = func_type->param_count - 1; idx >= 0; idx--) if (func_type->param_count > 0) {
for (idx = (int32)(func_type->param_count - 1); idx >= 0; idx--)
POP_TYPE(func_type->types[idx]); POP_TYPE(func_type->types[idx]);
}
PUSH_TYPE(func_type->types[func_type->param_count]); PUSH_TYPE(func_type->types[func_type->param_count]);
break; break;

View File

@ -12,6 +12,7 @@
#include "wasm_platform_log.h" #include "wasm_platform_log.h"
#include "wasm_memory.h" #include "wasm_memory.h"
#include "mem_alloc.h" #include "mem_alloc.h"
#include "bh_common.h"
static void static void
@ -77,9 +78,9 @@ wasm_runtime_call_wasm(WASMModuleInstance *module_inst,
uint32 stack_size; uint32 stack_size;
/* Set to 8 bytes align */ /* Set to 8 bytes align */
stack = (stack + 7) & ~7; stack = (stack + 7) & (uintptr_t)~7;
stack_size = exec_env->stack_size stack_size = (uint32)(exec_env->stack_size
- (stack - (uintptr_t)exec_env->stack); - (stack - (uintptr_t)exec_env->stack));
if (!exec_env->stack || exec_env->stack_size <= 0 if (!exec_env->stack || exec_env->stack_size <= 0
|| exec_env->stack_size < stack - (uintptr_t)exec_env->stack) { || exec_env->stack_size < stack - (uintptr_t)exec_env->stack) {
@ -171,18 +172,19 @@ memory_instantiate(uint32 init_page_count, uint32 max_page_count,
char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
WASMMemoryInstance *memory; WASMMemoryInstance *memory;
uint32 total_size = offsetof(WASMMemoryInstance, base_addr) + uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
NumBytesPerPage * init_page_count + NumBytesPerPage * (uint64)init_page_count +
addr_data_size + global_data_size; addr_data_size + global_data_size;
/* Allocate memory space, addr data and global data */ /* Allocate memory space, addr data and global data */
if (!(memory = wasm_malloc(total_size))) { if (total_size >= UINT32_MAX
|| !(memory = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate memory failed: allocate memory failed."); "Instantiate memory failed: allocate memory failed.");
return NULL; return NULL;
} }
memset(memory, 0, total_size); memset(memory, 0, (uint32)total_size);
memory->cur_page_count = init_page_count; memory->cur_page_count = init_page_count;
memory->max_page_count = max_page_count; memory->max_page_count = max_page_count;
@ -238,23 +240,23 @@ memories_instantiate(const WASMModule *module, uint32 addr_data_size,
WASMImport *import; WASMImport *import;
uint32 mem_index = 0, i, memory_count = uint32 mem_index = 0, i, memory_count =
module->import_memory_count + module->memory_count; module->import_memory_count + module->memory_count;
uint32 total_size; uint64 total_size;
WASMMemoryInstance **memories, *memory; WASMMemoryInstance **memories, *memory;
if (memory_count == 0 && global_data_size > 0) if (memory_count == 0 && global_data_size > 0)
memory_count = 1; memory_count = 1;
total_size = sizeof(WASMMemoryInstance*) * memory_count; total_size = sizeof(WASMMemoryInstance*) * (uint64)memory_count;
memories = wasm_malloc(total_size);
if (!memories) { if (total_size >= UINT32_MAX
|| !(memories = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate memory failed: " "Instantiate memory failed: "
"allocate memory failed."); "allocate memory failed.");
return NULL; return NULL;
} }
memset(memories, 0, total_size); memset(memories, 0, (uint32)total_size);
/* instantiate memories from import section */ /* instantiate memories from import section */
import = module->import_memories; import = module->import_memories;
@ -329,24 +331,26 @@ tables_instantiate(const WASMModule *module,
WASMImport *import; WASMImport *import;
uint32 table_index = 0, i, table_count = uint32 table_index = 0, i, table_count =
module->import_table_count + module->table_count; module->import_table_count + module->table_count;
uint32 total_size = sizeof(WASMTableInstance*) * table_count; uint64 total_size = sizeof(WASMTableInstance*) * (uint64)table_count;
WASMTableInstance **tables = wasm_malloc(total_size), *table; WASMTableInstance **tables, *table;
if (!tables) { if (total_size >= UINT32_MAX
|| !(tables = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate table failed: " "Instantiate table failed: "
"allocate memory failed."); "allocate memory failed.");
return NULL; return NULL;
} }
memset(tables, 0, total_size); memset(tables, 0, (uint32)total_size);
/* instantiate tables from import section */ /* instantiate tables from import section */
import = module->import_tables; import = module->import_tables;
for (i = 0; i < module->import_table_count; i++, import++) { for (i = 0; i < module->import_table_count; i++, import++) {
total_size = offsetof(WASMTableInstance, base_addr) + total_size = offsetof(WASMTableInstance, base_addr) +
sizeof(uint32) * import->u.table.init_size; sizeof(uint32) * (uint64)import->u.table.init_size;
if (!(table = tables[table_index++] = wasm_malloc(total_size))) { if (total_size >= UINT32_MAX
|| !(table = tables[table_index++] = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate table failed: " "Instantiate table failed: "
"allocate memory failed."); "allocate memory failed.");
@ -354,7 +358,7 @@ tables_instantiate(const WASMModule *module,
return NULL; return NULL;
} }
memset(table, 0, total_size); memset(table, 0, (uint32)total_size);
table->cur_size = import->u.table.init_size; table->cur_size = import->u.table.init_size;
table->max_size = import->u.table.max_size; table->max_size = import->u.table.max_size;
} }
@ -362,8 +366,9 @@ tables_instantiate(const WASMModule *module,
/* instantiate tables from table section */ /* instantiate tables from table section */
for (i = 0; i < module->table_count; i++) { for (i = 0; i < module->table_count; i++) {
total_size = offsetof(WASMTableInstance, base_addr) + total_size = offsetof(WASMTableInstance, base_addr) +
sizeof(uint32) * module->tables[i].init_size; sizeof(uint32) * (uint64)module->tables[i].init_size;
if (!(table = tables[table_index++] = wasm_malloc(total_size))) { if (total_size >= UINT32_MAX
|| !(table = tables[table_index++] = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate table failed: " "Instantiate table failed: "
"allocate memory failed."); "allocate memory failed.");
@ -371,7 +376,7 @@ tables_instantiate(const WASMModule *module,
return NULL; return NULL;
} }
memset(table, 0, total_size); memset(table, 0, (uint32)total_size);
table->cur_size = module->tables[i].init_size; table->cur_size = module->tables[i].init_size;
table->max_size = module->tables[i].max_size; table->max_size = module->tables[i].max_size;
} }
@ -399,24 +404,26 @@ functions_deinstantiate(WASMFunctionInstance *functions, uint32 count)
static bool static bool
function_init_local_offsets(WASMFunctionInstance *func) function_init_local_offsets(WASMFunctionInstance *func)
{ {
uint16 local_offset = 0; uint32 local_offset = 0;
WASMType *param_type = func->u.func->func_type; WASMType *param_type = func->u.func->func_type;
uint32 param_count = param_type->param_count; uint32 param_count = param_type->param_count;
uint8 *param_types = param_type->types; uint8 *param_types = param_type->types;
uint32 local_count = func->u.func->local_count; uint32 local_count = func->u.func->local_count;
uint8 *local_types = func->u.func->local_types; uint8 *local_types = func->u.func->local_types;
uint32 i, total_size = (param_count + local_count) * sizeof(uint16); uint32 i;
uint64 total_size = sizeof(uint16) * (uint64)(param_count + local_count);
if (!(func->local_offsets = wasm_malloc(total_size))) if (total_size >= UINT32_MAX
|| !(func->local_offsets = wasm_malloc((uint32)total_size)))
return false; return false;
for (i = 0; i < param_count; i++) { for (i = 0; i < param_count; i++) {
func->local_offsets[i] = local_offset; func->local_offsets[i] = (uint16)local_offset;
local_offset += wasm_value_type_cell_num(param_types[i]); local_offset += wasm_value_type_cell_num(param_types[i]);
} }
for (i = 0; i < local_count; i++) { for (i = 0; i < local_count; i++) {
func->local_offsets[param_count + i] = local_offset; func->local_offsets[param_count + i] = (uint16)local_offset;
local_offset += wasm_value_type_cell_num(local_types[i]); local_offset += wasm_value_type_cell_num(local_types[i]);
} }
@ -434,17 +441,18 @@ functions_instantiate(const WASMModule *module,
WASMImport *import; WASMImport *import;
uint32 i, function_count = uint32 i, function_count =
module->import_function_count + module->function_count; module->import_function_count + module->function_count;
uint32 total_size = sizeof(WASMFunctionInstance) * function_count; uint64 total_size = sizeof(WASMFunctionInstance) * (uint64)function_count;
WASMFunctionInstance *functions = wasm_malloc(total_size), *function; WASMFunctionInstance *functions, *function;
if (!functions) { if (total_size >= UINT32_MAX
|| !(functions = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate function failed: " "Instantiate function failed: "
"allocate memory failed."); "allocate memory failed.");
return NULL; return NULL;
} }
memset(functions, 0, total_size); memset(functions, 0, (uint32)total_size);
/* instantiate functions from import section */ /* instantiate functions from import section */
function = functions; function = functions;
@ -459,6 +467,12 @@ functions_instantiate(const WASMModule *module,
wasm_type_return_cell_num(import->u.function.func_type); wasm_type_return_cell_num(import->u.function.func_type);
function->local_cell_num = 0; function->local_cell_num = 0;
function->param_count =
(uint16)function->u.func_import->func_type->param_count;
function->local_count = 0;
function->param_types = function->u.func_import->func_type->types;
function->local_types = NULL;
function++; function++;
} }
@ -475,6 +489,11 @@ functions_instantiate(const WASMModule *module,
wasm_get_cell_num(function->u.func->local_types, wasm_get_cell_num(function->u.func->local_types,
function->u.func->local_count); function->u.func->local_count);
function->param_count = (uint16)function->u.func->func_type->param_count;
function->local_count = (uint16)function->u.func->local_count;
function->param_types = function->u.func->func_type->types;
function->local_types = function->u.func->local_types;
if (!function_init_local_offsets(function)) { if (!function_init_local_offsets(function)) {
functions_deinstantiate(functions, function_count); functions_deinstantiate(functions, function_count);
return NULL; return NULL;
@ -510,17 +529,18 @@ globals_instantiate(const WASMModule *module,
uint32 addr_data_offset = 0, global_data_offset = 0; uint32 addr_data_offset = 0, global_data_offset = 0;
uint32 i, global_count = uint32 i, global_count =
module->import_global_count + module->global_count; module->import_global_count + module->global_count;
uint32 total_size = sizeof(WASMGlobalInstance) * global_count; uint64 total_size = sizeof(WASMGlobalInstance) * (uint64)global_count;
WASMGlobalInstance *globals = wasm_malloc(total_size), *global; WASMGlobalInstance *globals, *global;
if (!globals) { if (total_size >= UINT32_MAX
|| !(globals = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate global failed: " "Instantiate global failed: "
"allocate memory failed."); "allocate memory failed.");
return NULL; return NULL;
} }
memset(globals, 0, total_size); memset(globals, 0, (uint32)total_size);
/* instantiate globals from import section */ /* instantiate globals from import section */
global = globals; global = globals;
@ -535,7 +555,7 @@ globals_instantiate(const WASMModule *module,
global_data_offset += wasm_value_type_size(global->type); global_data_offset += wasm_value_type_size(global->type);
if (global->is_addr) if (global->is_addr)
addr_data_offset += sizeof(uint32); addr_data_offset += (uint32)sizeof(uint32);
global++; global++;
} }
@ -550,7 +570,7 @@ globals_instantiate(const WASMModule *module,
global_data_offset += wasm_value_type_size(global->type); global_data_offset += wasm_value_type_size(global->type);
if (global->is_addr) if (global->is_addr)
addr_data_offset += sizeof(uint32); addr_data_offset += (uint32)sizeof(uint32);
global++; global++;
} }
@ -583,7 +603,7 @@ globals_instantiate_fix(WASMGlobalInstance *globals,
} }
else if (!strcmp(import->u.names.field_name, "DYNAMICTOP_PTR")) { else if (!strcmp(import->u.names.field_name, "DYNAMICTOP_PTR")) {
global->initial_value.i32 = global->initial_value.i32 =
NumBytesPerPage * module_inst->default_memory->cur_page_count; (int32)(NumBytesPerPage * module_inst->default_memory->cur_page_count);
module_inst->DYNAMICTOP_PTR_offset = global->data_offset; module_inst->DYNAMICTOP_PTR_offset = global->data_offset;
} }
else if (!strcmp(import->u.names.field_name, "STACKTOP")) { else if (!strcmp(import->u.names.field_name, "STACKTOP")) {
@ -604,7 +624,8 @@ globals_instantiate_fix(WASMGlobalInstance *globals,
global->initial_value = globals[init_expr->u.global_index].initial_value; global->initial_value = globals[init_expr->u.global_index].initial_value;
} }
else { else {
memcpy(&global->initial_value, &init_expr->u, sizeof(int64)); bh_memcpy_s(&global->initial_value, sizeof(WASMValue),
&init_expr->u, sizeof(init_expr->u));
} }
global++; global++;
} }
@ -647,16 +668,18 @@ export_functions_instantiate(const WASMModule *module,
{ {
WASMExportFuncInstance *export_funcs, *export_func; WASMExportFuncInstance *export_funcs, *export_func;
WASMExport *export = module->exports; WASMExport *export = module->exports;
uint32 i, total_size = sizeof(WASMExportFuncInstance) * export_func_count; uint32 i;
uint64 total_size = sizeof(WASMExportFuncInstance) * (uint64)export_func_count;
if (!(export_func = export_funcs = wasm_malloc(total_size))) { if (total_size >= UINT32_MAX
|| !(export_func = export_funcs = wasm_malloc((uint32)total_size))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate export function failed: " "Instantiate export function failed: "
"allocate memory failed."); "allocate memory failed.");
return NULL; return NULL;
} }
memset(export_funcs, 0, total_size); memset(export_funcs, 0, (uint32)total_size);
for (i = 0; i < module->export_count; i++, export++) for (i = 0; i < module->export_count; i++, export++)
if (export->kind == EXPORT_KIND_FUNC) { if (export->kind == EXPORT_KIND_FUNC) {
@ -715,6 +738,204 @@ execute_start_function(WASMModuleInstance *module_inst)
return wasm_runtime_call_wasm(module_inst, NULL, func, 0, NULL); return wasm_runtime_call_wasm(module_inst, NULL, func, 0, NULL);
} }
#if WASM_ENABLE_WASI != 0
static bool
wasm_runtime_init_wasi(WASMModuleInstance *module_inst,
const char *dir_list[], uint32 dir_count,
const char *map_dir_list[], uint32 map_dir_count,
const char *env[], uint32 env_count,
const char *argv[], uint32 argc,
char *error_buf, uint32 error_buf_size)
{
size_t *argv_offsets = NULL;
char *argv_buf = NULL;
size_t *env_offsets = NULL;
char *env_buf = NULL;
uint64 argv_buf_len = 0, env_buf_len = 0;
uint32 argv_buf_offset = 0, env_buf_offset = 0;
struct fd_table *curfds;
struct fd_prestats *prestats;
struct argv_environ_values *argv_environ;
int32 offset_argv_offsets = 0, offset_env_offsets = 0;
int32 offset_argv_buf = 0, offset_env_buf = 0;
int32 offset_curfds = 0;
int32 offset_prestats = 0;
int32 offset_argv_environ = 0;
__wasi_fd_t wasm_fd = 3;
int32 raw_fd;
char *path, resolved_path[PATH_MAX];
uint64 total_size;
uint32 i;
if (!module_inst->default_memory) {
argv_environ = module_inst->wasi_ctx.argv_environ = NULL;
prestats = module_inst->wasi_ctx.prestats = NULL;
curfds = module_inst->wasi_ctx.curfds = NULL;
return true;
}
/* process argv[0], trip the path and suffix, only keep the program name */
for (i = 0; i < argc; i++)
argv_buf_len += strlen(argv[i]) + 1;
total_size = sizeof(size_t) * (uint64)argc;
if (total_size >= UINT32_MAX
|| !(offset_argv_offsets = wasm_runtime_module_malloc
(module_inst, (uint32)total_size))
|| argv_buf_len >= UINT32_MAX
|| !(offset_argv_buf = wasm_runtime_module_malloc
(module_inst, (uint32)argv_buf_len))) {
set_error_buf(error_buf, error_buf_size,
"Init wasi environment failed: allocate memory failed.");
goto fail;
}
argv_offsets = (size_t*)
wasm_runtime_addr_app_to_native(module_inst, offset_argv_offsets);
argv_buf = (char*)
wasm_runtime_addr_app_to_native(module_inst, offset_argv_buf);
for (i = 0; i < argc; i++) {
argv_offsets[i] = argv_buf_offset;
bh_strcpy_s(argv_buf + argv_buf_offset,
(uint32)argv_buf_len - argv_buf_offset, argv[i]);
argv_buf_offset += (uint32)(strlen(argv[i]) + 1);
}
for (i = 0; i < env_count; i++)
env_buf_len += strlen(env[i]) + 1;
total_size = sizeof(size_t) * (uint64)argc;
if (total_size >= UINT32_MAX
|| !(offset_env_offsets = wasm_runtime_module_malloc
(module_inst, (uint32)total_size))
|| env_buf_len >= UINT32_MAX
|| !(offset_env_buf = wasm_runtime_module_malloc
(module_inst, (uint32)env_buf_len))) {
set_error_buf(error_buf, error_buf_size,
"Init wasi environment failed: allocate memory failed.");
goto fail;
}
env_offsets = (size_t*)
wasm_runtime_addr_app_to_native(module_inst, offset_env_offsets);
env_buf = (char*)
wasm_runtime_addr_app_to_native(module_inst, offset_env_buf);
for (i = 0; i < env_count; i++) {
env_offsets[i] = env_buf_offset;
bh_strcpy_s(env_buf + env_buf_offset,
(uint32)env_buf_len - env_buf_offset, env[i]);
env_buf_offset += (uint32)(strlen(env[i]) + 1);
}
if (!(offset_curfds = wasm_runtime_module_malloc
(module_inst, sizeof(struct fd_table)))
|| !(offset_prestats = wasm_runtime_module_malloc
(module_inst, sizeof(struct fd_prestats)))
|| !(offset_argv_environ = wasm_runtime_module_malloc
(module_inst, sizeof(struct argv_environ_values)))) {
set_error_buf(error_buf, error_buf_size,
"Init wasi environment failed: allocate memory failed.");
goto fail;
}
curfds = module_inst->wasi_ctx.curfds = (struct fd_table*)
wasm_runtime_addr_app_to_native(module_inst, offset_curfds);
prestats = module_inst->wasi_ctx.prestats = (struct fd_prestats*)
wasm_runtime_addr_app_to_native(module_inst, offset_prestats);
argv_environ = module_inst->wasi_ctx.argv_environ =
(struct argv_environ_values*)wasm_runtime_addr_app_to_native
(module_inst, offset_argv_environ);
fd_table_init(curfds);
fd_prestats_init(prestats);
if (!argv_environ_init(argv_environ,
argv_offsets, argc,
argv_buf, argv_buf_len,
env_offsets, env_count,
env_buf, env_buf_len)) {
set_error_buf(error_buf, error_buf_size,
"Init wasi environment failed: "
"init argument environment failed.");
goto fail;
}
/* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */
if (!fd_table_insert_existing(curfds, 0, 0)
|| !fd_table_insert_existing(curfds, 1, 1)
|| !fd_table_insert_existing(curfds, 2, 2)) {
set_error_buf(error_buf, error_buf_size,
"Init wasi environment failed: init fd table failed.");
goto fail;
}
wasm_fd = 3;
for (i = 0; i < dir_count; i++, wasm_fd++) {
path = realpath(dir_list[i], resolved_path);
if (!path) {
if (error_buf)
snprintf(error_buf, error_buf_size,
"error while pre-opening directory %s: %d\n",
dir_list[i], errno);
goto fail;
}
raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
if (raw_fd == -1) {
if (error_buf)
snprintf(error_buf, error_buf_size,
"error while pre-opening directory %s: %d\n",
dir_list[i], errno);
goto fail;
}
fd_table_insert_existing(curfds, wasm_fd, raw_fd);
fd_prestats_insert(prestats, dir_list[i], wasm_fd);
}
return true;
fail:
if (offset_curfds != 0)
wasm_runtime_module_free(module_inst, offset_curfds);
if (offset_prestats != 0)
wasm_runtime_module_free(module_inst, offset_prestats);
if (offset_argv_environ != 0)
wasm_runtime_module_free(module_inst, offset_argv_environ);
if (offset_argv_buf)
wasm_runtime_module_free(module_inst, offset_argv_buf);
if (offset_argv_offsets)
wasm_runtime_module_free(module_inst, offset_argv_offsets);
if (offset_env_buf)
wasm_runtime_module_free(module_inst, offset_env_buf);
if (offset_env_offsets)
wasm_runtime_module_free(module_inst, offset_env_offsets);
return false;
}
static void
wasm_runtime_destroy_wasi(WASMModuleInstance *module_inst)
{
WASIContext *wasi_ctx = &module_inst->wasi_ctx;
if (wasi_ctx->argv_environ)
argv_environ_destroy(wasi_ctx->argv_environ);
if (wasi_ctx->curfds)
fd_table_destroy(wasi_ctx->curfds);
if (wasi_ctx->prestats)
fd_prestats_destroy(wasi_ctx->prestats);
}
WASIContext *
wasm_runtime_get_wasi_ctx(WASMModuleInstance *module_inst)
{
return &module_inst->wasi_ctx;
}
#endif
/** /**
* Instantiate module * Instantiate module
*/ */
@ -754,14 +975,14 @@ wasm_runtime_instantiate(WASMModule *module,
return NULL; return NULL;
/* Allocate the memory */ /* Allocate the memory */
if (!(module_inst = wasm_malloc(sizeof(WASMModuleInstance)))) { if (!(module_inst = wasm_malloc((uint32)sizeof(WASMModuleInstance)))) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"Instantiate module failed: allocate memory failed."); "Instantiate module failed: allocate memory failed.");
globals_deinstantiate(globals); globals_deinstantiate(globals);
return NULL; return NULL;
} }
memset(module_inst, 0, sizeof(WASMModuleInstance)); memset(module_inst, 0, (uint32)sizeof(WASMModuleInstance));
module_inst->global_count = global_count; module_inst->global_count = global_count;
module_inst->globals = globals; module_inst->globals = globals;
@ -818,7 +1039,7 @@ wasm_runtime_instantiate(WASMModule *module,
else { else {
*(int32*)addr_data = global->initial_value.i32; *(int32*)addr_data = global->initial_value.i32;
/* Store the offset to memory data for global of addr */ /* Store the offset to memory data for global of addr */
*(int32*)global_data = addr_data - memory_data; *(int32*)global_data = (int32)(addr_data - memory_data);
addr_data += sizeof(int32); addr_data += sizeof(int32);
} }
global_data += sizeof(int32); global_data += sizeof(int32);
@ -826,7 +1047,8 @@ wasm_runtime_instantiate(WASMModule *module,
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
case VALUE_TYPE_F64: case VALUE_TYPE_F64:
wasm_assert(!global->is_addr); wasm_assert(!global->is_addr);
memcpy(global_data, &global->initial_value.i64, sizeof(int64)); bh_memcpy_s(global_data, (uint32)(global_data_end - global_data),
&global->initial_value.i64, sizeof(int64));
global_data += sizeof(int64); global_data += sizeof(int64);
break; break;
default: default:
@ -880,7 +1102,8 @@ wasm_runtime_instantiate(WASMModule *module,
return NULL; return NULL;
} }
memcpy(memory_data + base_offset, data_seg->data, length); bh_memcpy_s(memory_data + base_offset, memory_size - base_offset,
data_seg->data, length);
} }
} }
} }
@ -909,10 +1132,10 @@ wasm_runtime_instantiate(WASMModule *module,
if ((uint32)table_seg->base_offset.u.i32 < if ((uint32)table_seg->base_offset.u.i32 <
module_inst->default_table->cur_size) { module_inst->default_table->cur_size) {
length = table_seg->function_count; length = table_seg->function_count;
if (table_seg->base_offset.u.i32 + length > if ((uint32)table_seg->base_offset.u.i32 + length >
module_inst->default_table->cur_size) module_inst->default_table->cur_size)
length = module_inst->default_table->cur_size length = module_inst->default_table->cur_size
- table_seg->base_offset.u.i32; - (uint32)table_seg->base_offset.u.i32;
/* Check function index */ /* Check function index */
for (j = 0; j < length; j++) { for (j = 0; j < length; j++) {
if (table_seg->func_indexes[j] >= module_inst->function_count) { if (table_seg->func_indexes[j] >= module_inst->function_count) {
@ -922,12 +1145,31 @@ wasm_runtime_instantiate(WASMModule *module,
return NULL; return NULL;
} }
} }
memcpy(table_data + table_seg->base_offset.u.i32, bh_memcpy_s(table_data + table_seg->base_offset.u.i32,
table_seg->func_indexes, length * sizeof(uint32)); (uint32)((module_inst->default_table->cur_size
- (uint32)table_seg->base_offset.u.i32)
* sizeof(uint32)),
table_seg->func_indexes, (uint32)(length * sizeof(uint32)));
} }
} }
} }
#if WASM_ENABLE_WASI != 0
if (!wasm_runtime_init_wasi(module_inst,
module->wasi_args.dir_list,
module->wasi_args.dir_count,
module->wasi_args.map_dir_list,
module->wasi_args.map_dir_count,
module->wasi_args.env,
module->wasi_args.env_count,
module->wasi_args.argv,
module->wasi_args.argc,
error_buf, error_buf_size)) {
wasm_runtime_deinstantiate(module_inst);
return NULL;
}
#endif
if (module->start_function != (uint32)-1) { if (module->start_function != (uint32)-1) {
wasm_assert(module->start_function >= module->import_function_count); wasm_assert(module->start_function >= module->import_function_count);
module_inst->start_function = module_inst->start_function =
@ -968,6 +1210,10 @@ wasm_runtime_deinstantiate(WASMModuleInstance *module_inst)
if (!module_inst) if (!module_inst)
return; return;
#if WASM_ENABLE_WASI != 0
wasm_runtime_destroy_wasi(module_inst);
#endif
if (module_inst->memory_count > 0) if (module_inst->memory_count > 0)
memories_deinstantiate(module_inst->memories, module_inst->memory_count); memories_deinstantiate(module_inst->memories, module_inst->memory_count);
else if (module_inst->memories != NULL && module_inst->global_count > 0) else if (module_inst->memories != NULL && module_inst->global_count > 0)
@ -1018,15 +1264,15 @@ wasm_runtime_set_ext_memory(WASMModuleInstance *module_inst,
#endif #endif
bool bool
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count) wasm_runtime_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
{ {
#if WASM_ENABLE_MEMORY_GROW != 0 #if WASM_ENABLE_MEMORY_GROW != 0
WASMMemoryInstance *memory = module->default_memory; WASMMemoryInstance *memory = module->default_memory;
WASMMemoryInstance *new_memory; WASMMemoryInstance *new_memory;
uint32 total_page_count = inc_page_count + memory->cur_page_count; uint32 total_page_count = inc_page_count + memory->cur_page_count;
uint32 total_size = offsetof(WASMMemoryInstance, base_addr) + uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
memory->addr_data_size + memory->addr_data_size +
NumBytesPerPage * total_page_count + NumBytesPerPage * (uint64)total_page_count +
memory->global_data_size; memory->global_data_size;
if (inc_page_count <= 0) if (inc_page_count <= 0)
@ -1039,7 +1285,8 @@ wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
return false; return false;
} }
if (!(new_memory = wasm_malloc(total_size))) { if (total_size >= UINT32_MAX
|| !(new_memory = wasm_malloc((uint32)total_size))) {
wasm_runtime_set_exception(module, "fail to enlarge memory."); wasm_runtime_set_exception(module, "fail to enlarge memory.");
return false; return false;
} }
@ -1059,11 +1306,13 @@ wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
new_memory->end_addr = new_memory->global_data + memory->global_data_size; new_memory->end_addr = new_memory->global_data + memory->global_data_size;
/* Copy addr data and memory data */ /* Copy addr data and memory data */
memcpy(new_memory->addr_data, memory->addr_data, bh_memcpy_s(new_memory->addr_data,
memory->global_data - memory->addr_data); (uint32)(memory->global_data - memory->addr_data),
memory->addr_data,
(uint32)(memory->global_data - memory->addr_data));
/* Copy global data */ /* Copy global data */
memcpy(new_memory->global_data, memory->global_data, bh_memcpy_s(new_memory->global_data, new_memory->global_data_size,
memory->global_data_size); memory->global_data, memory->global_data_size);
/* Init free space of new memory */ /* Init free space of new memory */
memset(new_memory->memory_data + NumBytesPerPage * memory->cur_page_count, memset(new_memory->memory_data + NumBytesPerPage * memory->cur_page_count,
0, NumBytesPerPage * (total_page_count - memory->cur_page_count)); 0, NumBytesPerPage * (total_page_count - memory->cur_page_count));
@ -1097,7 +1346,7 @@ get_package_type(const uint8 *buf, uint32 size)
WASMExecEnv* WASMExecEnv*
wasm_runtime_create_exec_env(uint32 stack_size) wasm_runtime_create_exec_env(uint32 stack_size)
{ {
WASMExecEnv *exec_env = wasm_malloc(sizeof(WASMExecEnv)); WASMExecEnv *exec_env = wasm_malloc((uint32)sizeof(WASMExecEnv));
if (exec_env) { if (exec_env) {
if (!(exec_env->stack = wasm_malloc(stack_size))) { if (!(exec_env->stack = wasm_malloc(stack_size))) {
wasm_free(exec_env); wasm_free(exec_env);
@ -1139,7 +1388,7 @@ wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32 size)
wasm_runtime_set_exception(module_inst, "out of memory"); wasm_runtime_set_exception(module_inst, "out of memory");
return 0; return 0;
} }
return memory->heap_base_offset + (addr - memory->heap_data); return memory->heap_base_offset + (int32)(addr - memory->heap_data);
} }
void void
@ -1161,7 +1410,7 @@ wasm_runtime_module_dup_data(WASMModuleInstance *module_inst,
if (buffer_offset != 0) { if (buffer_offset != 0) {
char *buffer; char *buffer;
buffer = wasm_runtime_addr_app_to_native(module_inst, buffer_offset); buffer = wasm_runtime_addr_app_to_native(module_inst, buffer_offset);
memcpy(buffer, src, size); bh_memcpy_s(buffer, size, src, size);
} }
return buffer_offset; return buffer_offset;
} }
@ -1174,7 +1423,7 @@ wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst,
uint8 *addr; uint8 *addr;
/* integer overflow check */ /* integer overflow check */
if(app_offset + size < app_offset) { if(app_offset + (int32)size < app_offset) {
goto fail; goto fail;
} }
@ -1294,11 +1543,11 @@ wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst,
WASMMemoryInstance *memory = module_inst->default_memory; WASMMemoryInstance *memory = module_inst->default_memory;
if (memory->base_addr <= (uint8*)native_ptr if (memory->base_addr <= (uint8*)native_ptr
&& (uint8*)native_ptr < memory->end_addr) && (uint8*)native_ptr < memory->end_addr)
return (uint8*)native_ptr - memory->memory_data; return (int32)((uint8*)native_ptr - memory->memory_data);
else if (memory->heap_data <= (uint8*)native_ptr else if (memory->heap_data <= (uint8*)native_ptr
&& (uint8*)native_ptr < memory->heap_data_end) && (uint8*)native_ptr < memory->heap_data_end)
return memory->heap_base_offset return memory->heap_base_offset
+ ((uint8*)native_ptr - memory->heap_data); + (int32)((uint8*)native_ptr - memory->heap_data);
#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
else if (module_inst->ext_mem_data else if (module_inst->ext_mem_data
&& module_inst->ext_mem_data <= (uint8*)native_ptr && module_inst->ext_mem_data <= (uint8*)native_ptr
@ -1321,14 +1570,14 @@ wasm_runtime_get_app_addr_range(WASMModuleInstance *module_inst,
if (0 <= app_offset && app_offset < memory->heap_base_offset) { if (0 <= app_offset && app_offset < memory->heap_base_offset) {
app_start_offset = 0; app_start_offset = 0;
app_end_offset = NumBytesPerPage * memory->cur_page_count; app_end_offset = (int32)(NumBytesPerPage * memory->cur_page_count);
} }
else if (memory->heap_base_offset < app_offset else if (memory->heap_base_offset < app_offset
&& app_offset < memory->heap_base_offset && app_offset < memory->heap_base_offset
+ (memory->heap_data_end - memory->heap_data)) { + (memory->heap_data_end - memory->heap_data)) {
app_start_offset = memory->heap_base_offset; app_start_offset = memory->heap_base_offset;
app_end_offset = memory->heap_base_offset app_end_offset = memory->heap_base_offset
+ (memory->heap_data_end - memory->heap_data); + (int32)(memory->heap_data_end - memory->heap_data);
} }
#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
else if (module_inst->ext_mem_data else if (module_inst->ext_mem_data
@ -1479,7 +1728,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
#endif #endif
if (argc1 > sizeof(argv_buf) / sizeof(uint32)) { if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
size = ((uint64)sizeof(uint32)) * argc1; size = sizeof(uint32) * (uint64)argc1;
if (size >= UINT_MAX if (size >= UINT_MAX
|| !(argv1 = wasm_malloc((uint32)size))) { || !(argv1 = wasm_malloc((uint32)size))) {
wasm_runtime_set_exception(module_inst, "allocate memory failed."); wasm_runtime_set_exception(module_inst, "allocate memory failed.");
@ -1524,7 +1773,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
else { else {
switch (func_type->types[func_type->param_count]) { switch (func_type->types[func_type->param_count]) {
case VALUE_TYPE_I32: case VALUE_TYPE_I32:
ret[0] = invokeNative_Int32(func_ptr, argv1, argc1); ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
break; break;
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, argc1)); PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, argc1));
@ -1587,9 +1836,9 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
argc1 = 1 + MAX_REG_FLOATS + func_type->param_count + 2; argc1 = 1 + MAX_REG_FLOATS + func_type->param_count + 2;
if (argc1 > sizeof(argv_buf) / sizeof(uint64)) { if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
size = sizeof(uint64) * argc1; size = sizeof(uint64) * (uint64)argc1;
if (size >= UINT32_MAX if (size >= UINT32_MAX
|| !(argv1 = wasm_malloc(size))) { || !(argv1 = wasm_malloc((uint32)size))) {
wasm_runtime_set_exception(module_inst, "allocate memory failed."); wasm_runtime_set_exception(module_inst, "allocate memory failed.");
return false; return false;
} }
@ -1641,7 +1890,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
else { else {
switch (func_type->types[func_type->param_count]) { switch (func_type->types[func_type->param_count]) {
case VALUE_TYPE_I32: case VALUE_TYPE_I32:
ret[0] = invokeNative_Int32(func_ptr, argv1, n_stacks); ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
break; break;
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, n_stacks)); PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, n_stacks));

View File

@ -9,6 +9,10 @@
#include "wasm.h" #include "wasm.h"
#include "wasm_thread.h" #include "wasm_thread.h"
#include "wasm_hashmap.h" #include "wasm_hashmap.h"
#if WASM_ENABLE_WASI != 0
#include "wasmtime_ssp.h"
#include "posix.h"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -81,6 +85,10 @@ typedef struct WASMGlobalInstance {
typedef struct WASMFunctionInstance { typedef struct WASMFunctionInstance {
/* whether it is import function or WASM function */ /* whether it is import function or WASM function */
bool is_import_func; bool is_import_func;
/* parameter count */
uint16 param_count;
/* local variable count, 0 for import function */
uint16 local_count;
/* cell num of parameters */ /* cell num of parameters */
uint16 param_cell_num; uint16 param_cell_num;
/* cell num of return type */ /* cell num of return type */
@ -88,6 +96,10 @@ typedef struct WASMFunctionInstance {
/* cell num of local variables, 0 for import function */ /* cell num of local variables, 0 for import function */
uint16 local_cell_num; uint16 local_cell_num;
uint16 *local_offsets; uint16 *local_offsets;
/* parameter types */
uint8 *param_types;
/* local types, NULL for import function */
uint8 *local_types;
union { union {
WASMFunctionImport *func_import; WASMFunctionImport *func_import;
WASMFunction *func; WASMFunction *func;
@ -106,6 +118,14 @@ typedef enum {
Package_Type_Unknown = 0xFFFF Package_Type_Unknown = 0xFFFF
} PackageType; } PackageType;
#if WASM_ENABLE_WASI != 0
typedef struct WASIContext {
struct fd_table *curfds;
struct fd_prestats *prestats;
struct argv_environ_values *argv_environ;
} WASIContext;
#endif
typedef struct WASMModuleInstance { typedef struct WASMModuleInstance {
/* Module instance type, for module instance loaded from /* Module instance type, for module instance loaded from
WASM bytecode binary, this field is Wasm_Module_Bytecode; WASM bytecode binary, this field is Wasm_Module_Bytecode;
@ -133,6 +153,10 @@ typedef struct WASMModuleInstance {
WASMModule *module; WASMModule *module;
#if WASM_ENABLE_WASI != 0
WASIContext wasi_ctx;
#endif
uint32 DYNAMICTOP_PTR_offset; uint32 DYNAMICTOP_PTR_offset;
uint32 temp_ret; uint32 temp_ret;
uint32 llvm_stack; uint32 llvm_stack;
@ -271,7 +295,7 @@ wasm_runtime_get_exception(WASMModuleInstance *module);
* @return return true if enlarge successfully, false otherwise * @return return true if enlarge successfully, false otherwise
*/ */
bool bool
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count); wasm_runtime_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count);
/* See wasm_export.h for description */ /* See wasm_export.h for description */
WASMModuleInstance * WASMModuleInstance *

View File

@ -0,0 +1,220 @@
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.
--- LLVM Exceptions to the Apache 2.0 License ----
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
In addition, if you combine or link compiled forms of this Software with
software that is licensed under the GPLv2 ("Combined Software") and if a
court of competent jurisdiction determines that the patent provision (Section
3), the indemnity provision (Section 9) or other Section of the License
conflicts with the conditions of the GPLv2, you may retroactively and
prospectively choose to deem waived or otherwise exclude such Section(s) of
the License, but only in their entirety and only with respect to the Combined
Software.

View File

@ -0,0 +1,7 @@
Please see the LICENSE file in each top-level directory for the terms applicable to that directory and its relative sub-directories.
The relevant directories and licenses are:
src/ - BSD-2-Clause; see src/LICENSE for details
include/ - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
polyfill/clang/ - MIT; see the header of polyfill/clang/stdatomic.h for details

View File

@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View File

@ -0,0 +1,866 @@
/*
* Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
*
* This file declares an interface similar to WASI, but augmented to expose
* some implementation details such as the curfds arguments that we pass
* around to avoid storing them in TLS.
*/
#ifndef WASMTIME_SSP_H
#define WASMTIME_SSP_H
#include <stddef.h>
#include <stdint.h>
_Static_assert(_Alignof(int8_t) == 1, "non-wasi data layout");
_Static_assert(_Alignof(uint8_t) == 1, "non-wasi data layout");
_Static_assert(_Alignof(int16_t) == 2, "non-wasi data layout");
_Static_assert(_Alignof(uint16_t) == 2, "non-wasi data layout");
_Static_assert(_Alignof(int32_t) == 4, "non-wasi data layout");
_Static_assert(_Alignof(uint32_t) == 4, "non-wasi data layout");
_Static_assert(_Alignof(int64_t) == 8, "non-wasi data layout");
_Static_assert(_Alignof(uint64_t) == 8, "non-wasi data layout");
#ifdef __cplusplus
extern "C" {
#endif
typedef uint8_t __wasi_advice_t;
#define __WASI_ADVICE_NORMAL (0)
#define __WASI_ADVICE_SEQUENTIAL (1)
#define __WASI_ADVICE_RANDOM (2)
#define __WASI_ADVICE_WILLNEED (3)
#define __WASI_ADVICE_DONTNEED (4)
#define __WASI_ADVICE_NOREUSE (5)
typedef uint32_t __wasi_clockid_t;
#define __WASI_CLOCK_REALTIME (0)
#define __WASI_CLOCK_MONOTONIC (1)
#define __WASI_CLOCK_PROCESS_CPUTIME_ID (2)
#define __WASI_CLOCK_THREAD_CPUTIME_ID (3)
typedef uint64_t __wasi_device_t;
typedef uint64_t __wasi_dircookie_t;
#define __WASI_DIRCOOKIE_START (0)
typedef uint16_t __wasi_errno_t;
#define __WASI_ESUCCESS (0)
#define __WASI_E2BIG (1)
#define __WASI_EACCES (2)
#define __WASI_EADDRINUSE (3)
#define __WASI_EADDRNOTAVAIL (4)
#define __WASI_EAFNOSUPPORT (5)
#define __WASI_EAGAIN (6)
#define __WASI_EALREADY (7)
#define __WASI_EBADF (8)
#define __WASI_EBADMSG (9)
#define __WASI_EBUSY (10)
#define __WASI_ECANCELED (11)
#define __WASI_ECHILD (12)
#define __WASI_ECONNABORTED (13)
#define __WASI_ECONNREFUSED (14)
#define __WASI_ECONNRESET (15)
#define __WASI_EDEADLK (16)
#define __WASI_EDESTADDRREQ (17)
#define __WASI_EDOM (18)
#define __WASI_EDQUOT (19)
#define __WASI_EEXIST (20)
#define __WASI_EFAULT (21)
#define __WASI_EFBIG (22)
#define __WASI_EHOSTUNREACH (23)
#define __WASI_EIDRM (24)
#define __WASI_EILSEQ (25)
#define __WASI_EINPROGRESS (26)
#define __WASI_EINTR (27)
#define __WASI_EINVAL (28)
#define __WASI_EIO (29)
#define __WASI_EISCONN (30)
#define __WASI_EISDIR (31)
#define __WASI_ELOOP (32)
#define __WASI_EMFILE (33)
#define __WASI_EMLINK (34)
#define __WASI_EMSGSIZE (35)
#define __WASI_EMULTIHOP (36)
#define __WASI_ENAMETOOLONG (37)
#define __WASI_ENETDOWN (38)
#define __WASI_ENETRESET (39)
#define __WASI_ENETUNREACH (40)
#define __WASI_ENFILE (41)
#define __WASI_ENOBUFS (42)
#define __WASI_ENODEV (43)
#define __WASI_ENOENT (44)
#define __WASI_ENOEXEC (45)
#define __WASI_ENOLCK (46)
#define __WASI_ENOLINK (47)
#define __WASI_ENOMEM (48)
#define __WASI_ENOMSG (49)
#define __WASI_ENOPROTOOPT (50)
#define __WASI_ENOSPC (51)
#define __WASI_ENOSYS (52)
#define __WASI_ENOTCONN (53)
#define __WASI_ENOTDIR (54)
#define __WASI_ENOTEMPTY (55)
#define __WASI_ENOTRECOVERABLE (56)
#define __WASI_ENOTSOCK (57)
#define __WASI_ENOTSUP (58)
#define __WASI_ENOTTY (59)
#define __WASI_ENXIO (60)
#define __WASI_EOVERFLOW (61)
#define __WASI_EOWNERDEAD (62)
#define __WASI_EPERM (63)
#define __WASI_EPIPE (64)
#define __WASI_EPROTO (65)
#define __WASI_EPROTONOSUPPORT (66)
#define __WASI_EPROTOTYPE (67)
#define __WASI_ERANGE (68)
#define __WASI_EROFS (69)
#define __WASI_ESPIPE (70)
#define __WASI_ESRCH (71)
#define __WASI_ESTALE (72)
#define __WASI_ETIMEDOUT (73)
#define __WASI_ETXTBSY (74)
#define __WASI_EXDEV (75)
#define __WASI_ENOTCAPABLE (76)
typedef uint16_t __wasi_eventrwflags_t;
#define __WASI_EVENT_FD_READWRITE_HANGUP (0x0001)
typedef uint8_t __wasi_eventtype_t;
#define __WASI_EVENTTYPE_CLOCK (0)
#define __WASI_EVENTTYPE_FD_READ (1)
#define __WASI_EVENTTYPE_FD_WRITE (2)
typedef uint32_t __wasi_exitcode_t;
typedef uint32_t __wasi_fd_t;
typedef uint16_t __wasi_fdflags_t;
#define __WASI_FDFLAG_APPEND (0x0001)
#define __WASI_FDFLAG_DSYNC (0x0002)
#define __WASI_FDFLAG_NONBLOCK (0x0004)
#define __WASI_FDFLAG_RSYNC (0x0008)
#define __WASI_FDFLAG_SYNC (0x0010)
typedef int64_t __wasi_filedelta_t;
typedef uint64_t __wasi_filesize_t;
typedef uint8_t __wasi_filetype_t;
#define __WASI_FILETYPE_UNKNOWN (0)
#define __WASI_FILETYPE_BLOCK_DEVICE (1)
#define __WASI_FILETYPE_CHARACTER_DEVICE (2)
#define __WASI_FILETYPE_DIRECTORY (3)
#define __WASI_FILETYPE_REGULAR_FILE (4)
#define __WASI_FILETYPE_SOCKET_DGRAM (5)
#define __WASI_FILETYPE_SOCKET_STREAM (6)
#define __WASI_FILETYPE_SYMBOLIC_LINK (7)
typedef uint16_t __wasi_fstflags_t;
#define __WASI_FILESTAT_SET_ATIM (0x0001)
#define __WASI_FILESTAT_SET_ATIM_NOW (0x0002)
#define __WASI_FILESTAT_SET_MTIM (0x0004)
#define __WASI_FILESTAT_SET_MTIM_NOW (0x0008)
typedef uint64_t __wasi_inode_t;
typedef uint32_t __wasi_linkcount_t;
typedef uint32_t __wasi_lookupflags_t;
#define __WASI_LOOKUP_SYMLINK_FOLLOW (0x00000001)
typedef uint16_t __wasi_oflags_t;
#define __WASI_O_CREAT (0x0001)
#define __WASI_O_DIRECTORY (0x0002)
#define __WASI_O_EXCL (0x0004)
#define __WASI_O_TRUNC (0x0008)
typedef uint16_t __wasi_riflags_t;
#define __WASI_SOCK_RECV_PEEK (0x0001)
#define __WASI_SOCK_RECV_WAITALL (0x0002)
typedef uint64_t __wasi_rights_t;
#define __WASI_RIGHT_FD_DATASYNC (0x0000000000000001)
#define __WASI_RIGHT_FD_READ (0x0000000000000002)
#define __WASI_RIGHT_FD_SEEK (0x0000000000000004)
#define __WASI_RIGHT_FD_FDSTAT_SET_FLAGS (0x0000000000000008)
#define __WASI_RIGHT_FD_SYNC (0x0000000000000010)
#define __WASI_RIGHT_FD_TELL (0x0000000000000020)
#define __WASI_RIGHT_FD_WRITE (0x0000000000000040)
#define __WASI_RIGHT_FD_ADVISE (0x0000000000000080)
#define __WASI_RIGHT_FD_ALLOCATE (0x0000000000000100)
#define __WASI_RIGHT_PATH_CREATE_DIRECTORY (0x0000000000000200)
#define __WASI_RIGHT_PATH_CREATE_FILE (0x0000000000000400)
#define __WASI_RIGHT_PATH_LINK_SOURCE (0x0000000000000800)
#define __WASI_RIGHT_PATH_LINK_TARGET (0x0000000000001000)
#define __WASI_RIGHT_PATH_OPEN (0x0000000000002000)
#define __WASI_RIGHT_FD_READDIR (0x0000000000004000)
#define __WASI_RIGHT_PATH_READLINK (0x0000000000008000)
#define __WASI_RIGHT_PATH_RENAME_SOURCE (0x0000000000010000)
#define __WASI_RIGHT_PATH_RENAME_TARGET (0x0000000000020000)
#define __WASI_RIGHT_PATH_FILESTAT_GET (0x0000000000040000)
#define __WASI_RIGHT_PATH_FILESTAT_SET_SIZE (0x0000000000080000)
#define __WASI_RIGHT_PATH_FILESTAT_SET_TIMES (0x0000000000100000)
#define __WASI_RIGHT_FD_FILESTAT_GET (0x0000000000200000)
#define __WASI_RIGHT_FD_FILESTAT_SET_SIZE (0x0000000000400000)
#define __WASI_RIGHT_FD_FILESTAT_SET_TIMES (0x0000000000800000)
#define __WASI_RIGHT_PATH_SYMLINK (0x0000000001000000)
#define __WASI_RIGHT_PATH_REMOVE_DIRECTORY (0x0000000002000000)
#define __WASI_RIGHT_PATH_UNLINK_FILE (0x0000000004000000)
#define __WASI_RIGHT_POLL_FD_READWRITE (0x0000000008000000)
#define __WASI_RIGHT_SOCK_SHUTDOWN (0x0000000010000000)
typedef uint16_t __wasi_roflags_t;
#define __WASI_SOCK_RECV_DATA_TRUNCATED (0x0001)
typedef uint8_t __wasi_sdflags_t;
#define __WASI_SHUT_RD (0x01)
#define __WASI_SHUT_WR (0x02)
typedef uint16_t __wasi_siflags_t;
typedef uint8_t __wasi_signal_t;
// 0 is reserved; POSIX has special semantics for kill(pid, 0).
#define __WASI_SIGHUP (1)
#define __WASI_SIGINT (2)
#define __WASI_SIGQUIT (3)
#define __WASI_SIGILL (4)
#define __WASI_SIGTRAP (5)
#define __WASI_SIGABRT (6)
#define __WASI_SIGBUS (7)
#define __WASI_SIGFPE (8)
#define __WASI_SIGKILL (9)
#define __WASI_SIGUSR1 (10)
#define __WASI_SIGSEGV (11)
#define __WASI_SIGUSR2 (12)
#define __WASI_SIGPIPE (13)
#define __WASI_SIGALRM (14)
#define __WASI_SIGTERM (15)
#define __WASI_SIGCHLD (16)
#define __WASI_SIGCONT (17)
#define __WASI_SIGSTOP (18)
#define __WASI_SIGTSTP (19)
#define __WASI_SIGTTIN (20)
#define __WASI_SIGTTOU (21)
#define __WASI_SIGURG (22)
#define __WASI_SIGXCPU (23)
#define __WASI_SIGXFSZ (24)
#define __WASI_SIGVTALRM (25)
#define __WASI_SIGPROF (26)
#define __WASI_SIGWINCH (27)
#define __WASI_SIGPOLL (28)
#define __WASI_SIGPWR (29)
#define __WASI_SIGSYS (30)
typedef uint16_t __wasi_subclockflags_t;
#define __WASI_SUBSCRIPTION_CLOCK_ABSTIME (0x0001)
typedef uint64_t __wasi_timestamp_t;
typedef uint64_t __wasi_userdata_t;
typedef uint8_t __wasi_whence_t;
#define __WASI_WHENCE_CUR (0)
#define __WASI_WHENCE_END (1)
#define __WASI_WHENCE_SET (2)
typedef uint8_t __wasi_preopentype_t;
#define __WASI_PREOPENTYPE_DIR (0)
struct fd_table;
struct fd_prestats;
struct argv_environ_values;
typedef struct __wasi_dirent_t {
__wasi_dircookie_t d_next;
__wasi_inode_t d_ino;
uint32_t d_namlen;
__wasi_filetype_t d_type;
} __wasi_dirent_t;
_Static_assert(offsetof(__wasi_dirent_t, d_next) == 0, "non-wasi data layout");
_Static_assert(offsetof(__wasi_dirent_t, d_ino) == 8, "non-wasi data layout");
_Static_assert(offsetof(__wasi_dirent_t, d_namlen) == 16, "non-wasi data layout");
_Static_assert(offsetof(__wasi_dirent_t, d_type) == 20, "non-wasi data layout");
_Static_assert(sizeof(__wasi_dirent_t) == 24, "non-wasi data layout");
_Static_assert(_Alignof(__wasi_dirent_t) == 8, "non-wasi data layout");
typedef struct __wasi_event_t {
__wasi_userdata_t userdata;
__wasi_errno_t error;
__wasi_eventtype_t type;
union __wasi_event_u {
struct __wasi_event_u_fd_readwrite_t {
__wasi_filesize_t nbytes;
__wasi_eventrwflags_t flags;
} fd_readwrite;
} u;
} __wasi_event_t;
_Static_assert(offsetof(__wasi_event_t, userdata) == 0, "non-wasi data layout");
_Static_assert(offsetof(__wasi_event_t, error) == 8, "non-wasi data layout");
_Static_assert(offsetof(__wasi_event_t, type) == 10, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_event_t, u.fd_readwrite.nbytes) == 16, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_event_t, u.fd_readwrite.flags) == 24, "non-wasi data layout");
_Static_assert(sizeof(__wasi_event_t) == 32, "non-wasi data layout");
_Static_assert(_Alignof(__wasi_event_t) == 8, "non-wasi data layout");
typedef struct __wasi_prestat_t {
__wasi_preopentype_t pr_type;
union __wasi_prestat_u {
struct __wasi_prestat_u_dir_t {
size_t pr_name_len;
} dir;
} u;
} __wasi_prestat_t;
_Static_assert(offsetof(__wasi_prestat_t, pr_type) == 0, "non-wasi data layout");
_Static_assert(sizeof(void *) != 4 ||
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 4, "non-wasi data layout");
_Static_assert(sizeof(void *) != 8 ||
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 8, "non-wasi data layout");
_Static_assert(sizeof(void *) != 4 ||
sizeof(__wasi_prestat_t) == 8, "non-wasi data layout");
_Static_assert(sizeof(void *) != 8 ||
sizeof(__wasi_prestat_t) == 16, "non-wasi data layout");
_Static_assert(sizeof(void *) != 4 ||
_Alignof(__wasi_prestat_t) == 4, "non-wasi data layout");
_Static_assert(sizeof(void *) != 8 ||
_Alignof(__wasi_prestat_t) == 8, "non-wasi data layout");
typedef struct __wasi_fdstat_t {
__wasi_filetype_t fs_filetype;
__wasi_fdflags_t fs_flags;
__wasi_rights_t fs_rights_base;
__wasi_rights_t fs_rights_inheriting;
} __wasi_fdstat_t;
_Static_assert(
offsetof(__wasi_fdstat_t, fs_filetype) == 0, "non-wasi data layout");
_Static_assert(offsetof(__wasi_fdstat_t, fs_flags) == 2, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_fdstat_t, fs_rights_base) == 8, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_fdstat_t, fs_rights_inheriting) == 16,
"non-wasi data layout");
_Static_assert(sizeof(__wasi_fdstat_t) == 24, "non-wasi data layout");
_Static_assert(_Alignof(__wasi_fdstat_t) == 8, "non-wasi data layout");
typedef struct __wasi_filestat_t {
__wasi_device_t st_dev;
__wasi_inode_t st_ino;
__wasi_filetype_t st_filetype;
__wasi_linkcount_t st_nlink;
__wasi_filesize_t st_size;
__wasi_timestamp_t st_atim;
__wasi_timestamp_t st_mtim;
__wasi_timestamp_t st_ctim;
} __wasi_filestat_t;
_Static_assert(offsetof(__wasi_filestat_t, st_dev) == 0, "non-wasi data layout");
_Static_assert(offsetof(__wasi_filestat_t, st_ino) == 8, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_filestat_t, st_filetype) == 16, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_filestat_t, st_nlink) == 20, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_filestat_t, st_size) == 24, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_filestat_t, st_atim) == 32, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_filestat_t, st_mtim) == 40, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_filestat_t, st_ctim) == 48, "non-wasi data layout");
_Static_assert(sizeof(__wasi_filestat_t) == 56, "non-wasi data layout");
_Static_assert(_Alignof(__wasi_filestat_t) == 8, "non-wasi data layout");
typedef struct __wasi_ciovec_t {
const void *buf;
size_t buf_len;
} __wasi_ciovec_t;
_Static_assert(offsetof(__wasi_ciovec_t, buf) == 0, "non-wasi data layout");
_Static_assert(sizeof(void *) != 4 ||
offsetof(__wasi_ciovec_t, buf_len) == 4, "non-wasi data layout");
_Static_assert(sizeof(void *) != 8 ||
offsetof(__wasi_ciovec_t, buf_len) == 8, "non-wasi data layout");
_Static_assert(sizeof(void *) != 4 ||
sizeof(__wasi_ciovec_t) == 8, "non-wasi data layout");
_Static_assert(sizeof(void *) != 8 ||
sizeof(__wasi_ciovec_t) == 16, "non-wasi data layout");
_Static_assert(sizeof(void *) != 4 ||
_Alignof(__wasi_ciovec_t) == 4, "non-wasi data layout");
_Static_assert(sizeof(void *) != 8 ||
_Alignof(__wasi_ciovec_t) == 8, "non-wasi data layout");
typedef struct __wasi_iovec_t {
void *buf;
size_t buf_len;
} __wasi_iovec_t;
_Static_assert(offsetof(__wasi_iovec_t, buf) == 0, "non-wasi data layout");
_Static_assert(sizeof(void *) != 4 ||
offsetof(__wasi_iovec_t, buf_len) == 4, "non-wasi data layout");
_Static_assert(sizeof(void *) != 8 ||
offsetof(__wasi_iovec_t, buf_len) == 8, "non-wasi data layout");
_Static_assert(sizeof(void *) != 4 ||
sizeof(__wasi_iovec_t) == 8, "non-wasi data layout");
_Static_assert(sizeof(void *) != 8 ||
sizeof(__wasi_iovec_t) == 16, "non-wasi data layout");
_Static_assert(sizeof(void *) != 4 ||
_Alignof(__wasi_iovec_t) == 4, "non-wasi data layout");
_Static_assert(sizeof(void *) != 8 ||
_Alignof(__wasi_iovec_t) == 8, "non-wasi data layout");
typedef struct __wasi_subscription_t {
__wasi_userdata_t userdata;
__wasi_eventtype_t type;
union __wasi_subscription_u {
struct __wasi_subscription_u_clock_t {
__wasi_userdata_t identifier;
__wasi_clockid_t clock_id;
__wasi_timestamp_t timeout;
__wasi_timestamp_t precision;
__wasi_subclockflags_t flags;
} clock;
struct __wasi_subscription_u_fd_readwrite_t {
__wasi_fd_t fd;
} fd_readwrite;
} u;
} __wasi_subscription_t;
_Static_assert(
offsetof(__wasi_subscription_t, userdata) == 0, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_subscription_t, type) == 8, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_subscription_t, u.clock.identifier) == 16,
"non-wasi data layout");
_Static_assert(
offsetof(__wasi_subscription_t, u.clock.clock_id) == 24,
"non-wasi data layout");
_Static_assert(
offsetof(__wasi_subscription_t, u.clock.timeout) == 32, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_subscription_t, u.clock.precision) == 40,
"non-wasi data layout");
_Static_assert(
offsetof(__wasi_subscription_t, u.clock.flags) == 48, "non-wasi data layout");
_Static_assert(
offsetof(__wasi_subscription_t, u.fd_readwrite.fd) == 16,
"non-wasi data layout");
_Static_assert(sizeof(__wasi_subscription_t) == 56, "non-wasi data layout");
_Static_assert(_Alignof(__wasi_subscription_t) == 8, "non-wasi data layout");
#if defined(WASMTIME_SSP_WASI_API)
#define WASMTIME_SSP_SYSCALL_NAME(name) \
asm("__wasi_" #name)
#else
#define WASMTIME_SSP_SYSCALL_NAME(name)
#endif
__wasi_errno_t wasmtime_ssp_args_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ,
#endif
char **argv,
char *argv_buf
) WASMTIME_SSP_SYSCALL_NAME(args_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_args_sizes_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ,
#endif
size_t *argc,
size_t *argv_buf_size
) WASMTIME_SSP_SYSCALL_NAME(args_sizes_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_clock_res_get(
__wasi_clockid_t clock_id,
__wasi_timestamp_t *resolution
) WASMTIME_SSP_SYSCALL_NAME(clock_res_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_clock_time_get(
__wasi_clockid_t clock_id,
__wasi_timestamp_t precision,
__wasi_timestamp_t *time
) WASMTIME_SSP_SYSCALL_NAME(clock_time_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_environ_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ,
#endif
char **environ,
char *environ_buf
) WASMTIME_SSP_SYSCALL_NAME(environ_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_environ_sizes_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ,
#endif
size_t *environ_count,
size_t *environ_buf_size
) WASMTIME_SSP_SYSCALL_NAME(environ_sizes_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_prestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats,
#endif
__wasi_fd_t fd,
__wasi_prestat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_prestat_dir_name(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats,
#endif
__wasi_fd_t fd,
char *path,
size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_dir_name) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_close(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
struct fd_prestats *prestats,
#endif
__wasi_fd_t fd
) WASMTIME_SSP_SYSCALL_NAME(fd_close) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_datasync(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd
) WASMTIME_SSP_SYSCALL_NAME(fd_datasync) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_pread(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const __wasi_iovec_t *iovs,
size_t iovs_len,
__wasi_filesize_t offset,
size_t *nread
) WASMTIME_SSP_SYSCALL_NAME(fd_pread) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_pwrite(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const __wasi_ciovec_t *iovs,
size_t iovs_len,
__wasi_filesize_t offset,
size_t *nwritten
) WASMTIME_SSP_SYSCALL_NAME(fd_pwrite) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_read(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const __wasi_iovec_t *iovs,
size_t iovs_len,
size_t *nread
) WASMTIME_SSP_SYSCALL_NAME(fd_read) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_renumber(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
struct fd_prestats *prestats,
#endif
__wasi_fd_t from,
__wasi_fd_t to
) WASMTIME_SSP_SYSCALL_NAME(fd_renumber) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_seek(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filedelta_t offset,
__wasi_whence_t whence,
__wasi_filesize_t *newoffset
) WASMTIME_SSP_SYSCALL_NAME(fd_seek) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_tell(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filesize_t *newoffset
) WASMTIME_SSP_SYSCALL_NAME(fd_tell) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_fdstat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_fdstat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_fdstat_set_flags(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_fdflags_t flags
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_flags) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_fdstat_set_rights(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_rights) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_sync(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd
) WASMTIME_SSP_SYSCALL_NAME(fd_sync) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_write(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const __wasi_ciovec_t *iovs,
size_t iovs_len,
size_t *nwritten
) WASMTIME_SSP_SYSCALL_NAME(fd_write) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_advise(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filesize_t offset,
__wasi_filesize_t len,
__wasi_advice_t advice
) WASMTIME_SSP_SYSCALL_NAME(fd_advise) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_allocate(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filesize_t offset,
__wasi_filesize_t len
) WASMTIME_SSP_SYSCALL_NAME(fd_allocate) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_create_directory(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const char *path,
size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(path_create_directory) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_link(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t old_fd,
__wasi_lookupflags_t old_flags,
const char *old_path,
size_t old_path_len,
__wasi_fd_t new_fd,
const char *new_path,
size_t new_path_len
) WASMTIME_SSP_SYSCALL_NAME(path_link) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_open(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t dirfd,
__wasi_lookupflags_t dirflags,
const char *path,
size_t path_len,
__wasi_oflags_t oflags,
__wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting,
__wasi_fdflags_t fs_flags,
__wasi_fd_t *fd
) WASMTIME_SSP_SYSCALL_NAME(path_open) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_readdir(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
void *buf,
size_t buf_len,
__wasi_dircookie_t cookie,
size_t *bufused
) WASMTIME_SSP_SYSCALL_NAME(fd_readdir) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_readlink(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const char *path,
size_t path_len,
char *buf,
size_t buf_len,
size_t *bufused
) WASMTIME_SSP_SYSCALL_NAME(path_readlink) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_rename(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t old_fd,
const char *old_path,
size_t old_path_len,
__wasi_fd_t new_fd,
const char *new_path,
size_t new_path_len
) WASMTIME_SSP_SYSCALL_NAME(path_rename) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_filestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filestat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_filestat_set_times(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_timestamp_t st_atim,
__wasi_timestamp_t st_mtim,
__wasi_fstflags_t fstflags
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_times) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_fd_filestat_set_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filesize_t st_size
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_size) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_filestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_lookupflags_t flags,
const char *path,
size_t path_len,
__wasi_filestat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(path_filestat_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_filestat_set_times(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_lookupflags_t flags,
const char *path,
size_t path_len,
__wasi_timestamp_t st_atim,
__wasi_timestamp_t st_mtim,
__wasi_fstflags_t fstflags
) WASMTIME_SSP_SYSCALL_NAME(path_filestat_set_times) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_symlink(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
const char *old_path,
size_t old_path_len,
__wasi_fd_t fd,
const char *new_path,
size_t new_path_len
) WASMTIME_SSP_SYSCALL_NAME(path_symlink) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_unlink_file(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const char *path,
size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(path_unlink_file) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_path_remove_directory(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const char *path,
size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(path_remove_directory) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_poll_oneoff(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
const __wasi_subscription_t *in,
__wasi_event_t *out,
size_t nsubscriptions,
size_t *nevents
) WASMTIME_SSP_SYSCALL_NAME(poll_oneoff) __attribute__((__warn_unused_result__));
_Noreturn void wasmtime_ssp_proc_exit(
__wasi_exitcode_t rval
) WASMTIME_SSP_SYSCALL_NAME(proc_exit);
__wasi_errno_t wasmtime_ssp_proc_raise(
__wasi_signal_t sig
) WASMTIME_SSP_SYSCALL_NAME(proc_raise) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_random_get(
void *buf,
size_t buf_len
) WASMTIME_SSP_SYSCALL_NAME(random_get) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_recv(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
const __wasi_iovec_t *ri_data,
size_t ri_data_len,
__wasi_riflags_t ri_flags,
size_t *ro_datalen,
__wasi_roflags_t *ro_flags
) WASMTIME_SSP_SYSCALL_NAME(sock_recv) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_send(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
const __wasi_ciovec_t *si_data,
size_t si_data_len,
__wasi_siflags_t si_flags,
size_t *so_datalen
) WASMTIME_SSP_SYSCALL_NAME(sock_send) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_shutdown(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
__wasi_sdflags_t how
) WASMTIME_SSP_SYSCALL_NAME(sock_shutdown) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sched_yield(void)
WASMTIME_SSP_SYSCALL_NAME(sched_yield) __attribute__((__warn_unused_result__));
#ifdef __cplusplus
}
#endif
#undef WASMTIME_SSP_SYSCALL_NAME
#endif

View File

@ -0,0 +1,24 @@
All code is distributed under the following license:
Copyright (c) 2015 Nuxi, https://nuxi.nl/
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

View File

@ -0,0 +1,14 @@
This directory consists of selected files copied from the [libemulator]
directory in the [cloudabi-utils] repository, with minor modifications,
along with the accompanying LICENSE file from that repository.
The modifications are marked with `WASMTIME_*` preprocessor macros.
The files were copied at git revision
223dadc53248552db43e012c67ed08cf416a2b12
which is dated
Tue Jun 25 17:22:07 2019 -0700
.
[libemulator]: https://github.com/NuxiNL/cloudabi-utils/tree/master/src/libemulator
[cloudabi-utils]: https://github.com/NuxiNL/cloudabi-utils

View File

@ -0,0 +1,100 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef CONFIG_H
#define CONFIG_H
#include <stdlib.h>
#if defined(__FreeBSD__) || defined(__APPLE__)
#define CONFIG_HAS_ARC4RANDOM_BUF 1
#else
#define CONFIG_HAS_ARC4RANDOM_BUF 0
#endif
// On Linux, prefer to use getrandom, though it isn't available in
// GLIBC before 2.25.
#if defined(__linux__) && \
(!defined(__GLIBC__) || \
__GLIBC__ > 2 || \
(__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
#define CONFIG_HAS_GETRANDOM 1
#else
#define CONFIG_HAS_GETRANDOM 0
#endif
#if defined(__CloudABI__)
#define CONFIG_HAS_CAP_ENTER 1
#else
#define CONFIG_HAS_CAP_ENTER 0
#endif
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__EMSCRIPTEN__)
#define CONFIG_HAS_CLOCK_NANOSLEEP 1
#else
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
#endif
#if !defined(__APPLE__) && !defined(__FreeBSD__)
#define CONFIG_HAS_FDATASYNC 1
#else
#define CONFIG_HAS_FDATASYNC 0
#endif
#ifndef __CloudABI__
#define CONFIG_HAS_ISATTY 1
#else
#define CONFIG_HAS_ISATTY 0
#endif
#ifndef __APPLE__
#define CONFIG_HAS_POSIX_FALLOCATE 1
#else
#define CONFIG_HAS_POSIX_FALLOCATE 0
#endif
#ifndef __APPLE__
#define CONFIG_HAS_PREADV 1
#else
#define CONFIG_HAS_PREADV 0
#endif
#if defined(__APPLE__) || defined(__CloudABI__)
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1
#else
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
#endif
#ifndef __APPLE__
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
#else
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
#endif
#ifndef __APPLE__
#define CONFIG_HAS_PWRITEV 1
#else
#define CONFIG_HAS_PWRITEV 0
#endif
#ifdef __APPLE__
#define st_atimespec st_atim
#define st_mtimespec st_mtim
#define st_ctimespec st_ctim
#endif
#ifdef __APPLE__
#define CONFIG_TLS_USE_GSBASE 1
#else
#define CONFIG_TLS_USE_GSBASE 0
#endif
#endif

View File

@ -0,0 +1,215 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef LOCKING_H
#define LOCKING_H
#include "config.h"
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <time.h>
#ifndef __has_extension
#define __has_extension(x) 0
#endif
#if __has_extension(c_thread_safety_attributes)
#define LOCK_ANNOTATE(x) __attribute__((x))
#else
#define LOCK_ANNOTATE(x)
#endif
// Lock annotation macros.
#define LOCKABLE LOCK_ANNOTATE(lockable)
#define LOCKS_EXCLUSIVE(...) LOCK_ANNOTATE(exclusive_lock_function(__VA_ARGS__))
#define LOCKS_SHARED(...) LOCK_ANNOTATE(shared_lock_function(__VA_ARGS__))
#define TRYLOCKS_EXCLUSIVE(...) \
LOCK_ANNOTATE(exclusive_trylock_function(__VA_ARGS__))
#define TRYLOCKS_SHARED(...) LOCK_ANNOTATE(shared_trylock_function(__VA_ARGS__))
#define UNLOCKS(...) LOCK_ANNOTATE(unlock_function(__VA_ARGS__))
#define REQUIRES_EXCLUSIVE(...) \
LOCK_ANNOTATE(exclusive_locks_required(__VA_ARGS__))
#define REQUIRES_SHARED(...) LOCK_ANNOTATE(shared_locks_required(__VA_ARGS__))
#define REQUIRES_UNLOCKED(...) LOCK_ANNOTATE(locks_excluded(__VA_ARGS__))
#define NO_LOCK_ANALYSIS LOCK_ANNOTATE(no_thread_safety_analysis)
// Mutex that uses the lock annotations.
struct LOCKABLE mutex {
pthread_mutex_t object;
};
#define MUTEX_INITIALIZER \
{ PTHREAD_MUTEX_INITIALIZER }
static inline void mutex_init(struct mutex *lock) REQUIRES_UNLOCKED(*lock) {
pthread_mutex_init(&lock->object, NULL);
}
static inline void mutex_destroy(struct mutex *lock) REQUIRES_UNLOCKED(*lock) {
pthread_mutex_destroy(&lock->object);
}
static inline void mutex_lock(struct mutex *lock)
LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
pthread_mutex_lock(&lock->object);
}
static inline void mutex_unlock(struct mutex *lock)
UNLOCKS(*lock) NO_LOCK_ANALYSIS {
pthread_mutex_unlock(&lock->object);
}
// Read-write lock that uses the lock annotations.
struct LOCKABLE rwlock {
pthread_rwlock_t object;
};
static inline void rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock) {
pthread_rwlock_init(&lock->object, NULL);
}
static inline void rwlock_rdlock(struct rwlock *lock)
LOCKS_SHARED(*lock) NO_LOCK_ANALYSIS {
pthread_rwlock_rdlock(&lock->object);
}
static inline void rwlock_wrlock(struct rwlock *lock)
LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
pthread_rwlock_wrlock(&lock->object);
}
static inline void rwlock_unlock(struct rwlock *lock)
UNLOCKS(*lock) NO_LOCK_ANALYSIS {
pthread_rwlock_unlock(&lock->object);
}
// Condition variable that uses the lock annotations.
struct LOCKABLE cond {
pthread_cond_t object;
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
clockid_t clock;
#endif
};
static inline void cond_init_monotonic(struct cond *cond) {
#if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
pthread_condattr_t attr;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
pthread_cond_init(&cond->object, &attr);
pthread_condattr_destroy(&attr);
#else
pthread_cond_init(&cond->object, NULL);
#endif
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
cond->clock = CLOCK_MONOTONIC;
#endif
}
static inline void cond_init_realtime(struct cond *cond) {
pthread_cond_init(&cond->object, NULL);
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
cond->clock = CLOCK_REALTIME;
#endif
}
static inline void cond_destroy(struct cond *cond) {
pthread_cond_destroy(&cond->object);
}
static inline void cond_signal(struct cond *cond) {
pthread_cond_signal(&cond->object);
}
static inline bool cond_timedwait(struct cond *cond, struct mutex *lock,
uint64_t timeout, bool abstime)
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
struct timespec ts = {
.tv_sec = (time_t)(timeout / 1000000000),
.tv_nsec = (long)(timeout % 1000000000),
};
if (abstime) {
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
// No native support for sleeping on monotonic clocks. Convert the
// timeout to a relative value and then to an absolute value for the
// realtime clock.
if (cond->clock != CLOCK_REALTIME) {
struct timespec ts_monotonic;
clock_gettime(cond->clock, &ts_monotonic);
ts.tv_sec -= ts_monotonic.tv_sec;
ts.tv_nsec -= ts_monotonic.tv_nsec;
if (ts.tv_nsec < 0) {
ts.tv_nsec += 1000000000;
--ts.tv_sec;
}
struct timespec ts_realtime;
clock_gettime(CLOCK_REALTIME, &ts_realtime);
ts.tv_sec += ts_realtime.tv_sec;
ts.tv_nsec += ts_realtime.tv_nsec;
if (ts.tv_nsec >= 1000000000) {
ts.tv_nsec -= 1000000000;
++ts.tv_sec;
}
}
#endif
} else {
#if CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
// Implementation supports relative timeouts.
int ret =
pthread_cond_timedwait_relative_np(&cond->object, &lock->object, &ts);
assert((ret == 0 || ret == ETIMEDOUT) &&
"pthread_cond_timedwait_relative_np() failed");
return ret == ETIMEDOUT;
#else
// Convert to absolute timeout.
struct timespec ts_now;
#if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
clock_gettime(cond->clock, &ts_now);
#else
clock_gettime(CLOCK_REALTIME, &ts_now);
#endif
ts.tv_sec += ts_now.tv_sec;
ts.tv_nsec += ts_now.tv_nsec;
if (ts.tv_nsec >= 1000000000) {
ts.tv_nsec -= 1000000000;
++ts.tv_sec;
}
#endif
}
int ret = pthread_cond_timedwait(&cond->object, &lock->object, &ts);
assert((ret == 0 || ret == ETIMEDOUT) && "pthread_cond_timedwait() failed");
return ret == ETIMEDOUT;
}
static inline void cond_wait(struct cond *cond, struct mutex *lock)
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
pthread_cond_wait(&cond->object, &lock->object);
}
#endif

View File

@ -0,0 +1,42 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2015 Nuxi, https://nuxi.nl/
#ifndef COMMON_LIMITS_H
#define COMMON_LIMITS_H
#include <limits.h>
#define NUMERIC_MIN(t) \
_Generic((t)0, char \
: CHAR_MIN, signed char \
: SCHAR_MIN, unsigned char : 0, short \
: SHRT_MIN, unsigned short : 0, int \
: INT_MIN, unsigned int : 0, long \
: LONG_MIN, unsigned long : 0, long long \
: LLONG_MIN, unsigned long long : 0, default \
: (void)0)
#define NUMERIC_MAX(t) \
_Generic((t)0, char \
: CHAR_MAX, signed char \
: SCHAR_MAX, unsigned char \
: UCHAR_MAX, short \
: SHRT_MAX, unsigned short \
: USHRT_MAX, int \
: INT_MAX, unsigned int \
: UINT_MAX, long \
: LONG_MAX, unsigned long \
: ULONG_MAX, long long \
: LLONG_MAX, unsigned long long \
: ULLONG_MAX, default \
: (void)0)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016-2018 Nuxi, https://nuxi.nl/
#ifndef POSIX_H
#define POSIX_H
#include <stdbool.h>
#include <stddef.h>
#include "locking.h"
struct fd_entry;
struct fd_prestat;
struct syscalls;
struct fd_table {
struct rwlock lock;
struct fd_entry *entries;
size_t size;
size_t used;
};
struct fd_prestats {
struct rwlock lock;
struct fd_prestat *prestats;
size_t size;
size_t used;
};
struct argv_environ_values {
size_t argc;
size_t argv_buf_size;
char **argv;
char *argv_buf;
size_t environ_count;
size_t environ_buf_size;
char **environ;
char *environ_buf;
};
void fd_table_init(struct fd_table *);
bool fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
void fd_prestats_init(struct fd_prestats *);
bool fd_prestats_insert(struct fd_prestats *, const char *, __wasi_fd_t);
bool argv_environ_init(struct argv_environ_values *,
const size_t *argv_offsets, size_t argv_offsets_len,
const char *argv_buf, size_t argv_buf_len,
const size_t *environ_offsets, size_t environ_offsets_len,
const char *environ_buf, size_t environ_buf_len);
void argv_environ_destroy(struct argv_environ_values *argv_environ);
void fd_table_destroy(struct fd_table *ft);
void fd_prestats_destroy(struct fd_prestats *pt);
#endif

View File

@ -0,0 +1,92 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef QUEUE_H
#define QUEUE_H
#include <stddef.h>
// LIST: Double-linked list.
#define LIST_HEAD(name, type) \
struct name { \
struct type *l_first; \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *l_next; \
struct type **l_prev; \
}
#define LIST_FOREACH(var, head, field) \
for ((var) = (head)->l_first; (var) != NULL; (var) = (var)->field.l_next)
#define LIST_INIT(head) \
do { \
(head)->l_first = NULL; \
} while (0)
#define LIST_INSERT_HEAD(head, element, field) \
do { \
(element)->field.l_next = (head)->l_first; \
if ((head)->l_first != NULL) \
(head)->l_first->field.l_prev = &(element)->field.l_next; \
(head)->l_first = (element); \
(element)->field.l_prev = &(head)->l_first; \
} while (0)
#define LIST_REMOVE(element, field) \
do { \
if ((element)->field.l_next != NULL) \
(element)->field.l_next->field.l_prev = (element)->field.l_prev; \
*(element)->field.l_prev = (element)->field.l_next; \
} while (0)
// TAILQ: Double-linked list with tail pointer.
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *t_first; \
struct type **t_last; \
}
#define TAILQ_ENTRY(type) \
struct { \
struct type *t_next; \
struct type **t_prev; \
}
#define TAILQ_EMPTY(head) ((head)->t_first == NULL)
#define TAILQ_FIRST(head) ((head)->t_first)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = (head)->t_first; (var) != NULL; (var) = (var)->field.t_next)
#define TAILQ_INIT(head) \
do { \
(head)->t_first = NULL; \
(head)->t_last = &(head)->t_first; \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) \
do { \
(elm)->field.t_next = NULL; \
(elm)->field.t_prev = (head)->t_last; \
*(head)->t_last = (elm); \
(head)->t_last = &(elm)->field.t_next; \
} while (0)
#define TAILQ_REMOVE(head, element, field) \
do { \
if ((element)->field.t_next != NULL) \
(element)->field.t_next->field.t_prev = (element)->field.t_prev; \
else \
(head)->t_last = (element)->field.t_prev; \
*(element)->field.t_prev = (element)->field.t_next; \
} while (0)
#endif

View File

@ -0,0 +1,92 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#include "config.h"
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "random.h"
#if CONFIG_HAS_ARC4RANDOM_BUF
void random_buf(void *buf, size_t len) {
arc4random_buf(buf, len);
}
#elif CONFIG_HAS_GETRANDOM
#include <sys/random.h>
void random_buf(void *buf, size_t len) {
for (;;) {
ssize_t x = getrandom(buf, len, 0);
if (x < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "getrandom failed: %s", strerror(errno));
abort();
}
if (x == len)
return;
buf = (void *)((unsigned char *)buf + x);
len -= x;
}
}
#else
static int urandom;
static void open_urandom(void) {
urandom = open("/dev/urandom", O_RDONLY);
if (urandom < 0) {
fputs("Failed to open /dev/urandom\n", stderr);
abort();
}
}
void random_buf(void *buf, size_t len) {
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
pthread_once(&open_once, open_urandom);
if ((size_t)read(urandom, buf, len) != len) {
fputs("Short read on /dev/urandom\n", stderr);
abort();
}
}
#endif
// Calculates a random number within the range [0, upper - 1] without
// any modulo bias.
//
// The function below repeatedly obtains a random number from
// arc4random() until it lies within the range [2^k % upper, 2^k). As
// this range has length k * upper, we can safely obtain a number
// without any modulo bias.
uintmax_t random_uniform(uintmax_t upper) {
// Compute 2^k % upper
// == (2^k - upper) % upper
// == -upper % upper.
uintmax_t lower = -upper % upper;
for (;;) {
uintmax_t value;
random_buf(&value, sizeof(value));
if (value >= lower)
return value % upper;
}
}

View File

@ -0,0 +1,20 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef RANDOM_H
#define RANDOM_H
#include <stdint.h>
void random_buf(void *, size_t);
uintmax_t random_uniform(uintmax_t);
#endif

View File

@ -0,0 +1,47 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef REFCOUNT_H
#define REFCOUNT_H
#include <assert.h>
#include <stdatomic.h>
#include <stdbool.h>
#include "locking.h"
// Simple reference counter.
struct LOCKABLE refcount {
atomic_uint count;
};
#define PRODUCES(...) LOCKS_SHARED(__VA_ARGS__) NO_LOCK_ANALYSIS
#define CONSUMES(...) UNLOCKS(__VA_ARGS__) NO_LOCK_ANALYSIS
// Initialize the reference counter.
static void refcount_init(struct refcount *r, unsigned int count) PRODUCES(*r) {
atomic_init(&r->count, count);
}
// Increment the reference counter.
static inline void refcount_acquire(struct refcount *r) PRODUCES(*r) {
atomic_fetch_add_explicit(&r->count, 1, memory_order_acquire);
}
// Decrement the reference counter, returning whether the reference
// dropped to zero.
static inline bool refcount_release(struct refcount *r) CONSUMES(*r) {
int old = (int)atomic_fetch_sub_explicit(&r->count, 1, memory_order_release);
assert(old != 0 && "Reference count becoming negative");
return old == 1;
}
#endif

View File

@ -0,0 +1,83 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef RIGHTS_H
#define RIGHTS_H
#define RIGHTS_ALL \
(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ | \
__WASI_RIGHT_FD_SEEK | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_SYNC | __WASI_RIGHT_FD_TELL | __WASI_RIGHT_FD_WRITE | \
__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_FD_ALLOCATE | \
__WASI_RIGHT_PATH_CREATE_DIRECTORY | __WASI_RIGHT_PATH_CREATE_FILE | \
__WASI_RIGHT_PATH_LINK_SOURCE | __WASI_RIGHT_PATH_LINK_TARGET | \
__WASI_RIGHT_PATH_OPEN | __WASI_RIGHT_FD_READDIR | \
__WASI_RIGHT_PATH_READLINK | __WASI_RIGHT_PATH_RENAME_SOURCE | \
__WASI_RIGHT_PATH_RENAME_TARGET | __WASI_RIGHT_PATH_FILESTAT_GET | \
__WASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
__WASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
__WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_FILESTAT_SET_TIMES | \
__WASI_RIGHT_FD_FILESTAT_SET_SIZE | \
__WASI_RIGHT_PATH_SYMLINK | __WASI_RIGHT_PATH_UNLINK_FILE | \
__WASI_RIGHT_PATH_REMOVE_DIRECTORY | \
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
// Block and character device interaction is outside the scope of
// CloudABI. Simply allow everything.
#define RIGHTS_BLOCK_DEVICE_BASE RIGHTS_ALL
#define RIGHTS_BLOCK_DEVICE_INHERITING RIGHTS_ALL
#define RIGHTS_CHARACTER_DEVICE_BASE RIGHTS_ALL
#define RIGHTS_CHARACTER_DEVICE_INHERITING RIGHTS_ALL
// Only allow directory operations on directories. Directories can only
// yield file descriptors to other directories and files.
#define RIGHTS_DIRECTORY_BASE \
(__WASI_RIGHT_FD_FDSTAT_SET_FLAGS | __WASI_RIGHT_FD_SYNC | \
__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_PATH_CREATE_DIRECTORY | \
__WASI_RIGHT_PATH_CREATE_FILE | __WASI_RIGHT_PATH_LINK_SOURCE | \
__WASI_RIGHT_PATH_LINK_TARGET | __WASI_RIGHT_PATH_OPEN | \
__WASI_RIGHT_FD_READDIR | __WASI_RIGHT_PATH_READLINK | \
__WASI_RIGHT_PATH_RENAME_SOURCE | __WASI_RIGHT_PATH_RENAME_TARGET | \
__WASI_RIGHT_PATH_FILESTAT_GET | \
__WASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
__WASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
__WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_FILESTAT_SET_TIMES | \
__WASI_RIGHT_PATH_SYMLINK | __WASI_RIGHT_PATH_UNLINK_FILE | \
__WASI_RIGHT_PATH_REMOVE_DIRECTORY | \
__WASI_RIGHT_POLL_FD_READWRITE)
#define RIGHTS_DIRECTORY_INHERITING \
(RIGHTS_DIRECTORY_BASE | RIGHTS_REGULAR_FILE_BASE)
// Operations that apply to regular files.
#define RIGHTS_REGULAR_FILE_BASE \
(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ | \
__WASI_RIGHT_FD_SEEK | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_SYNC | __WASI_RIGHT_FD_TELL | __WASI_RIGHT_FD_WRITE | \
__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_FD_ALLOCATE | \
__WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_FILESTAT_SET_SIZE | \
__WASI_RIGHT_FD_FILESTAT_SET_TIMES | __WASI_RIGHT_POLL_FD_READWRITE)
#define RIGHTS_REGULAR_FILE_INHERITING 0
// Operations that apply to sockets and socket pairs.
#define RIGHTS_SOCKET_BASE \
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
#define RIGHTS_SOCKET_INHERITING RIGHTS_ALL
// Operations that apply to TTYs.
#define RIGHTS_TTY_BASE \
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
__WASI_RIGHT_POLL_FD_READWRITE)
#define RIGHTS_TTY_INHERITING 0
#endif

View File

@ -0,0 +1,17 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef SIGNALS_H
#define SIGNALS_H
void signals_init(void);
#endif

View File

@ -0,0 +1,33 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "str.h"
char *str_nullterminate(const char *s, size_t len) {
// Copy string.
char *ret = strndup(s, len);
if (ret == NULL)
return NULL;
// Ensure that it contains no null bytes within.
if (strlen(ret) != len) {
free(ret);
errno = EILSEQ;
return NULL;
}
return ret;
}

View File

@ -0,0 +1,19 @@
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
//
// Significant parts of this file are derived from cloudabi-utils. See
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
// for license information.
//
// The upstream file contains the following copyright notice:
//
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
#ifndef STR_H
#define STR_H
#include "config.h"
char *str_nullterminate(const char *, size_t);
#endif

View File

@ -0,0 +1,12 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (WASI_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
if (WASM_ENABLE_WASI EQUAL 1)
include_directories(${WASI_LIB_DIR}/sandboxed-system-primitives/include
${WASI_LIB_DIR}/sandboxed-system-primitives/src
)
file (GLOB_RECURSE source_all ${WASI_LIB_DIR}/sandboxed-system-primitives/*.c )
set (WASI_LIB_SOURCE ${source_all})
endif ()

View File

@ -1,38 +0,0 @@
Contiki is licensed under the 3-clause BSD license. This license gives
everyone the right to use and distribute the code, either in binary or
source code format, as long as the copyright license is retained in
the source code.
The copyright for different parts of the code is held by different
people and organizations, but the code is licensed under the same type
of license. The license text is:
* Copyright (c) (Year), (Name of copyright holder)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,8 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
COAP_ROOT=${ZEPHYR_BASE}/subsys/aee/Beihai/runtime/utils/coap
subdir-ccflags-y += -I${COAP_ROOT}/er-coap -I${COAP_ROOT}/extension
obj-y += er-coap/
obj-y += extension/

View File

@ -0,0 +1,30 @@
Copyright (c) (Year), (Name of copyright holder)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,4 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
obj-y += er-coap.o

View File

@ -0,0 +1,192 @@
/*
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Collection of constants specified in the CoAP standard.
* \author
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
*/
/**
* \addtogroup coap
* @{
*/
#ifndef COAP_CONSTANTS_H_
#define COAP_CONSTANTS_H_
#define COAP_DEFAULT_PORT 5683
#define COAP_DEFAULT_SECURE_PORT 5684
#define COAP_DEFAULT_MAX_AGE 60
#define COAP_RESPONSE_TIMEOUT 3
#define COAP_RESPONSE_RANDOM_FACTOR 1.5
#define COAP_MAX_RETRANSMIT 4
#define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */
#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */
#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */
#define COAP_HEADER_VERSION_MASK 0xC0
#define COAP_HEADER_VERSION_POSITION 6
#define COAP_HEADER_TYPE_MASK 0x30
#define COAP_HEADER_TYPE_POSITION 4
#define COAP_HEADER_TOKEN_LEN_MASK 0x0F
#define COAP_HEADER_TOKEN_LEN_POSITION 0
#define COAP_HEADER_OPTION_DELTA_MASK 0xF0
#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F
/* CoAP message types */
typedef enum {
COAP_TYPE_CON, /* confirmables */
COAP_TYPE_NON, /* non-confirmables */
COAP_TYPE_ACK, /* acknowledgements */
COAP_TYPE_RST /* reset */
} coap_message_type_t;
/* CoAP request method codes */
typedef enum {
COAP_GET = 1,
COAP_POST,
COAP_PUT,
COAP_DELETE
} coap_method_t;
/* CoAP response codes */
typedef enum {
NO_ERROR = 0,
CREATED_2_01 = 65, /* CREATED */
DELETED_2_02 = 66, /* DELETED */
VALID_2_03 = 67, /* NOT_MODIFIED */
CHANGED_2_04 = 68, /* CHANGED */
CONTENT_2_05 = 69, /* OK */
CONTINUE_2_31 = 95, /* CONTINUE */
BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */
UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */
BAD_OPTION_4_02 = 130, /* BAD_OPTION */
FORBIDDEN_4_03 = 131, /* FORBIDDEN */
NOT_FOUND_4_04 = 132, /* NOT_FOUND */
METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */
NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */
PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */
REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */
INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */
NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */
BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */
SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */
GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */
PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */
/* Erbium errors */
MEMORY_ALLOCATION_ERROR = 192,
PACKET_SERIALIZATION_ERROR,
/* Erbium hooks */
MANUAL_RESPONSE,
PING_RESPONSE
} coap_status_t;
/* CoAP header option numbers */
typedef enum {
COAP_OPTION_IF_MATCH = 1, /* 0-8 B */
COAP_OPTION_URI_HOST = 3, /* 1-255 B */
COAP_OPTION_ETAG = 4, /* 1-8 B */
COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */
COAP_OPTION_OBSERVE = 6, /* 0-3 B */
COAP_OPTION_URI_PORT = 7, /* 0-2 B */
COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */
COAP_OPTION_URI_PATH = 11, /* 0-255 B */
COAP_OPTION_CONTENT_FORMAT = 12, /* 0-2 B */
COAP_OPTION_MAX_AGE = 14, /* 0-4 B */
COAP_OPTION_URI_QUERY = 15, /* 0-255 B */
COAP_OPTION_ACCEPT = 17, /* 0-2 B */
COAP_OPTION_LOCATION_QUERY = 20, /* 0-255 B */
COAP_OPTION_BLOCK2 = 23, /* 1-3 B */
COAP_OPTION_BLOCK1 = 27, /* 1-3 B */
COAP_OPTION_SIZE2 = 28, /* 0-4 B */
COAP_OPTION_PROXY_URI = 35, /* 1-1034 B */
COAP_OPTION_PROXY_SCHEME = 39, /* 1-255 B */
COAP_OPTION_SIZE1 = 60, /* 0-4 B */
} coap_option_t;
/* CoAP Content-Formats */
typedef enum {
TEXT_PLAIN = 0,
TEXT_XML = 1,
TEXT_CSV = 2,
TEXT_HTML = 3,
IMAGE_GIF = 21,
IMAGE_JPEG = 22,
IMAGE_PNG = 23,
IMAGE_TIFF = 24,
AUDIO_RAW = 25,
VIDEO_RAW = 26,
APPLICATION_LINK_FORMAT = 40,
APPLICATION_XML = 41,
APPLICATION_OCTET_STREAM = 42,
APPLICATION_RDF_XML = 43,
APPLICATION_SOAP_XML = 44,
APPLICATION_ATOM_XML = 45,
APPLICATION_XMPP_XML = 46,
APPLICATION_EXI = 47,
APPLICATION_FASTINFOSET = 48,
APPLICATION_SOAP_FASTINFOSET = 49,
APPLICATION_JSON = 50,
APPLICATION_X_OBIX_BINARY = 51
} coap_content_format_t;
/**
* Resource flags for allowed methods and special functionalities.
*/
typedef enum {
NO_FLAGS = 0,
/* methods to handle */
METHOD_GET = (1 << 0),
METHOD_POST = (1 << 1),
METHOD_PUT = (1 << 2),
METHOD_DELETE = (1 << 3),
/* special flags */
HAS_SUB_RESOURCES = (1 << 4),
IS_SEPARATE = (1 << 5),
IS_OBSERVABLE = (1 << 6),
IS_PERIODIC = (1 << 7)
} coap_resource_flags_t;
#endif /* COAP_CONSTANTS_H_ */
/** @} */

View File

@ -1,75 +0,0 @@
/*
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Collection of default configuration values.
* \author
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
*/
#ifndef ER_COAP_CONF_H_
#define ER_COAP_CONF_H_
/* Features that can be disabled to achieve smaller memory footprint */
#define COAP_LINK_FORMAT_FILTERING 0
#define COAP_PROXY_OPTION_PROCESSING 0
/* Listening port for the CoAP REST Engine */
#ifndef COAP_SERVER_PORT
#define COAP_SERVER_PORT COAP_DEFAULT_PORT
#endif
/* The number of concurrent messages that can be stored for retransmission in the transaction layer. */
#ifndef COAP_MAX_OPEN_TRANSACTIONS
#define COAP_MAX_OPEN_TRANSACTIONS 4
#endif /* COAP_MAX_OPEN_TRANSACTIONS */
/* Maximum number of failed request attempts before action */
#ifndef COAP_MAX_ATTEMPTS
#define COAP_MAX_ATTEMPTS 4
#endif /* COAP_MAX_ATTEMPTS */
/* Conservative size limit, as not all options have to be set at the same time. Check when Proxy-Uri option is used */
#ifndef COAP_MAX_HEADER_SIZE /* Hdr CoF If-Match Obs Blo strings */
#define COAP_MAX_HEADER_SIZE 512
//(4 + COAP_TOKEN_LEN + 3 + 1 + COAP_ETAG_LEN + 4 + 4 + 30) /* 65 */
#endif /* COAP_MAX_HEADER_SIZE */
/* Number of observer slots (each takes abot xxx bytes) */
#ifndef COAP_MAX_OBSERVERS
#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS - 1
#endif /* COAP_MAX_OBSERVERS */
/* Interval in notifies in which NON notifies are changed to CON notifies to check client. */
#define COAP_OBSERVE_REFRESH_INTERVAL 20
#endif /* ER_COAP_CONF_H_ */

View File

@ -1,161 +0,0 @@
/*
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Collection of constants specified in the CoAP standard.
* \author
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
*/
#ifndef ER_COAP_CONSTANTS_H_
#define ER_COAP_CONSTANTS_H_
#define COAP_DEFAULT_PORT 5683
#define COAP_DEFAULT_MAX_AGE 60
#define COAP_RESPONSE_TIMEOUT 3
#define COAP_RESPONSE_RANDOM_FACTOR 1.5
#define COAP_MAX_RETRANSMIT 4
#define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */
#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */
#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */
#define COAP_HEADER_VERSION_MASK 0xC0
#define COAP_HEADER_VERSION_POSITION 6
#define COAP_HEADER_TYPE_MASK 0x30
#define COAP_HEADER_TYPE_POSITION 4
#define COAP_HEADER_TOKEN_LEN_MASK 0x0F
#define COAP_HEADER_TOKEN_LEN_POSITION 0
#define COAP_HEADER_OPTION_DELTA_MASK 0xF0
#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F
/* CoAP message types */
typedef enum {
COAP_TYPE_CON, /* confirmables */
COAP_TYPE_NON, /* non-confirmables */
COAP_TYPE_ACK, /* acknowledgements */
COAP_TYPE_RST /* reset */
} coap_message_type_t;
/* CoAP request method codes */
typedef enum {
COAP_GET = 1, COAP_POST, COAP_PUT, COAP_DELETE
} coap_method_t;
/* CoAP response codes */
typedef enum {
NO_ERROR = 0,
CREATED_2_01 = 65, /* CREATED */
DELETED_2_02 = 66, /* DELETED */
VALID_2_03 = 67, /* NOT_MODIFIED */
CHANGED_2_04 = 68, /* CHANGED */
CONTENT_2_05 = 69, /* OK */
CONTINUE_2_31 = 95, /* CONTINUE */
BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */
UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */
BAD_OPTION_4_02 = 130, /* BAD_OPTION */
FORBIDDEN_4_03 = 131, /* FORBIDDEN */
NOT_FOUND_4_04 = 132, /* NOT_FOUND */
METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */
NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */
PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */
REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */
INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */
NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */
BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */
SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */
GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */
PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */
/* Erbium errors */
MEMORY_ALLOCATION_ERROR = 192, PACKET_SERIALIZATION_ERROR,
/* Erbium hooks */
MANUAL_RESPONSE, PING_RESPONSE
} coap_status_t;
/* CoAP header option numbers */
typedef enum {
COAP_OPTION_IF_MATCH = 1, /* 0-8 B */
COAP_OPTION_URI_HOST = 3, /* 1-255 B */
COAP_OPTION_ETAG = 4, /* 1-8 B */
COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */
COAP_OPTION_OBSERVE = 6, /* 0-3 B */
COAP_OPTION_URI_PORT = 7, /* 0-2 B */
COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */
COAP_OPTION_URI_PATH = 11, /* 0-255 B */
COAP_OPTION_CONTENT_FORMAT = 12, /* 0-2 B */
COAP_OPTION_MAX_AGE = 14, /* 0-4 B */
COAP_OPTION_URI_QUERY = 15, /* 0-255 B */
COAP_OPTION_ACCEPT = 17, /* 0-2 B */
COAP_OPTION_LOCATION_QUERY = 20, /* 0-255 B */
COAP_OPTION_BLOCK2 = 23, /* 1-3 B */
COAP_OPTION_BLOCK1 = 27, /* 1-3 B */
COAP_OPTION_SIZE2 = 28, /* 0-4 B */
COAP_OPTION_PROXY_URI = 35, /* 1-1034 B */
COAP_OPTION_PROXY_SCHEME = 39, /* 1-255 B */
COAP_OPTION_SIZE1 = 60, /* 0-4 B */
} coap_option_t;
/* CoAP Content-Formats */
typedef enum {
TEXT_PLAIN = 0,
TEXT_XML = 1,
TEXT_CSV = 2,
TEXT_HTML = 3,
IMAGE_GIF = 21,
IMAGE_JPEG = 22,
IMAGE_PNG = 23,
IMAGE_TIFF = 24,
AUDIO_RAW = 25,
VIDEO_RAW = 26,
APPLICATION_LINK_FORMAT = 40,
APPLICATION_XML = 41,
APPLICATION_OCTET_STREAM = 42,
APPLICATION_RDF_XML = 43,
APPLICATION_SOAP_XML = 44,
APPLICATION_ATOM_XML = 45,
APPLICATION_XMPP_XML = 46,
APPLICATION_EXI = 47,
APPLICATION_FASTINFOSET = 48,
APPLICATION_SOAP_FASTINFOSET = 49,
APPLICATION_JSON = 50,
APPLICATION_X_OBIX_BINARY = 51
} coap_content_format_t;
#endif /* ER_COAP_CONSTANTS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,370 +0,0 @@
/*
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* An implementation of the Constrained Application Protocol (RFC).
* \author
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
*/
#ifndef ER_COAP_H_
#define ER_COAP_H_
#include "../extension/coap_platforms.h"
#include <stddef.h> /* for size_t */
#include <stdint.h>
//#include "contiki-net.h"
#include "er-coap-constants.h"
#include "er-coap-conf.h"
#ifdef __cplusplus
extern "C" {
#endif
/* sanity check for configured values */
#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE)
/*#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN)
#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE"
#endif
*/
/* ------------------------------------------------------ */
/* ------ section added by the coap request --------- */
/* ------------------------------------------------------ */
//typedef int (*restful_response_handler)(void *response,void *data);
#define RX_TIMEOUT (-1)
typedef int (*Tx_Data)(void * coap_ctx, const uip_ipaddr_t *dst_addr, void *buf, int len);
typedef int (*Rx_Data) (void * coap_ctx, void *buf, int len, int timeout);
typedef int (*Request_Handler) (void * coap_ctx, void *);
typedef int (*CoAP_Res_Handler) (void * request, void * response, char **out_payload, int * payload_len);
typedef struct _coap_resource_handler
{
struct _coap_resource_handler * next;
char * url;
CoAP_Res_Handler get_handler;
CoAP_Res_Handler put_handler;
CoAP_Res_Handler post_handler;
CoAP_Res_Handler other_handler; // create | delete
}coap_resource_handler_t;
typedef struct res_block_state
{
struct res_block_state * next;
char * url;
void * buffer;
int buffer_size;
uint32_t block_num;
uint16_t block_size;
uint16_t content_fmt;
uint32_t last_access;
uint8_t is_get;
} res_block_state_t;
typedef struct peer_block_state
{
struct peer_block_state * next;
struct net_addr_coap peer_addr;
res_block_state_t * list;
}peer_block_state_t;
typedef struct coap_context {
uint8_t * buf;
uint32_t buf_len; // the data length
uint32_t buf_size; // the malloced buffer size
struct net_addr_coap my_addr;
// the address associated with current buffer
struct net_addr_coap src_addr;
uint8_t status;
uint8_t is_used;
uint8_t response_on_not_found;
uint16_t default_retrans_cnt;
uint32_t default_retrans_ms;
Tx_Data tx_data;
Rx_Data rx_data;
int socket;
char * user_data;
peer_block_state_t * blockwise_list;
coap_resource_handler_t * resource_handlers;
void * transactions;
void * transaction_lock;
uint32_t last_checktime;
void * request_handler;
#ifdef WITH_DTLS
struct dtls_context_t *dtls_context;
dtls_handler_t dtls_handler;
struct process *process;
#endif /* WITH_DTLS */
} coap_context_t;
int add_resource_handler(coap_context_t * coap_ctx, coap_resource_handler_t * handler);
// coap_context_t * coap_context_new(uip_ipaddr_t *my_addr, uint16_t my_port); //CANNOTBUILD
void coap_context_close(coap_context_t *coap_ctx);
void coap_ctx_send(coap_context_t *coap_ctx, uint8_t *data,
uint16_t length);
/* ---------------- end of section ------------------ */
/* use Erbium CoAP for the REST Engine. Must come before include of rest-engine.h. */
//#define REST coap_rest_implementation
//#include "rest-engine.h"
/* REST_MAX_CHUNK_SIZE can be different from 2^x so we need to get next lower 2^x for COAP_MAX_BLOCK_SIZE */
#ifndef COAP_MAX_BLOCK_SIZE
#define COAP_MAX_BLOCK_SIZE (REST_MAX_CHUNK_SIZE < 32 ? 16 : \
(REST_MAX_CHUNK_SIZE < 64 ? 32 : \
(REST_MAX_CHUNK_SIZE < 128 ? 64 : \
(REST_MAX_CHUNK_SIZE < 256 ? 128 : \
(REST_MAX_CHUNK_SIZE < 512 ? 256 : \
(REST_MAX_CHUNK_SIZE < 1024 ? 512 : \
(REST_MAX_CHUNK_SIZE < 2048 ? 1024 : 2048)))))))
#endif /* COAP_MAX_BLOCK_SIZE */
/* direct access into the buffer */
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#ifdef NETSTACK_CONF_WITH_IPV6
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
#else
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
#endif
/* bitmap for set options */
enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 };
#define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE))
#define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE)))
/* parsed message struct */
typedef struct {
uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */
uint8_t version;
coap_message_type_t type;
uint8_t code;
uint16_t mid;
uint8_t token_len;
uint8_t token[COAP_TOKEN_LEN];
uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE + 1]; /* bitmap to check if option is set */
coap_content_format_t content_format; /* parse options once and store; allows setting options in random order */
uint32_t max_age;
uint8_t etag_len;
uint8_t etag[COAP_ETAG_LEN];
size_t proxy_uri_len;
const char *proxy_uri;
size_t proxy_scheme_len;
const char *proxy_scheme;
size_t uri_host_len;
const char *uri_host;
size_t location_path_len;
const char *location_path;
uint16_t uri_port;
size_t location_query_len;
const char *location_query;
size_t uri_path_len;
const char *uri_path;
int32_t observe;
coap_content_format_t accept;
uint8_t if_match_len;
uint8_t if_match[COAP_ETAG_LEN];
uint32_t block2_num;
uint8_t block2_more;
uint32_t block2_size;
uint32_t block2_offset;
uint32_t block1_num;
uint8_t block1_more;
uint32_t block1_size;
uint32_t block1_offset;
uint32_t size2;
uint32_t size1;
size_t uri_query_len;
const char *uri_query;
uint8_t if_none_match;
uint32_t payload_len;
uint8_t *payload;
} coap_packet_t;
/* option format serialization */
#define COAP_SERIALIZE_INT_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " [%u]\n", coap_pkt->field); \
option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \
current_number = number; \
}
#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \
coap_pkt->field[0], \
coap_pkt->field[1], \
coap_pkt->field[2], \
coap_pkt->field[3], \
coap_pkt->field[4], \
coap_pkt->field[5], \
coap_pkt->field[6], \
coap_pkt->field[7] \
); /* FIXME always prints 8 bytes */ \
option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, '\0'); \
current_number = number; \
}
#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \
if(IS_OPTION(coap_pkt, number)) { \
PRINTF(text " [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \
option += coap_serialize_array_option(number, current_number, option, (uint8_t *)coap_pkt->field, coap_pkt->field##_len, splitter); \
current_number = number; \
}
#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \
if(IS_OPTION(coap_pkt, number)) \
{ \
PRINTF(text " [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \
uint32_t block = coap_pkt->field##_num << 4; \
if(coap_pkt->field##_more) { block |= 0x8; } \
block |= 0xF & coap_log_2(coap_pkt->field##_size / 16); \
PRINTF(text " encoded: 0x%lX\n", block); \
option += coap_serialize_int_option(number, current_number, option, block); \
current_number = number; \
}
/* to store error code and human-readable payload */
extern coap_status_t erbium_status_code;
extern char *coap_error_message;
void coap_init_connection(uint16_t port);
uint16_t coap_get_mid(void);
void coap_init_message(void *packet, coap_message_type_t type, uint8_t code,
uint16_t mid);
size_t coap_serialize_message(void *packet, uint8_t *buffer);
void coap_send_message(coap_context_t*, uip_ipaddr_t *addr, uint16_t port, uint8_t *data,
uint16_t length);
coap_status_t coap_parse_message(void *request, uint8_t *data,
uint16_t data_len);
int coap_get_query_variable(void *packet, const char *name,
const char **output);
int coap_get_post_variable(void *packet, const char *name,
const char **output);
/*---------------------------------------------------------------------------*/
int coap_set_status_code(void *packet, unsigned int code);
int coap_set_token(void *packet, const uint8_t *token, size_t token_len);
int coap_get_header_content_format(void *packet, unsigned int *format);
int coap_set_header_content_format(void *packet, unsigned int format);
int coap_get_header_accept(void *packet, unsigned int *accept);
int coap_set_header_accept(void *packet, unsigned int accept);
int coap_get_header_max_age(void *packet, uint32_t *age);
int coap_set_header_max_age(void *packet, uint32_t age);
int coap_get_header_etag(void *packet, const uint8_t **etag);
int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len);
int coap_get_header_if_match(void *packet, const uint8_t **etag);
int coap_set_header_if_match(void *packet, const uint8_t *etag,
size_t etag_len);
int coap_get_header_if_none_match(void *packet);
int coap_set_header_if_none_match(void *packet);
int coap_get_header_proxy_uri(void *packet, const char **uri); /* in-place string might not be 0-terminated. */
int coap_set_header_proxy_uri(void *packet, const char *uri);
int coap_get_header_proxy_scheme(void *packet, const char **scheme); /* in-place string might not be 0-terminated. */
int coap_set_header_proxy_scheme(void *packet, const char *scheme);
int coap_get_header_uri_host(void *packet, const char **host); /* in-place string might not be 0-terminated. */
int coap_set_header_uri_host(void *packet, const char *host);
int coap_get_header_uri_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */
int coap_set_header_uri_path(void *packet, const char *path);
int coap_get_header_uri_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */
int coap_set_header_uri_query(void *packet, const char *query);
int coap_get_header_location_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */
int coap_set_header_location_path(void *packet, const char *path); /* also splits optional query into Location-Query option. */
int coap_get_header_location_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */
int coap_set_header_location_query(void *packet, const char *query);
int coap_get_header_observe(void *packet, uint32_t *observe);
int coap_set_header_observe(void *packet, uint32_t observe);
int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more,
uint32_t *size, uint32_t *offset);
int coap_set_header_block2(void *packet, uint32_t num, uint8_t more,
uint32_t size);
int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more,
uint16_t *size, uint32_t *offset);
int coap_set_header_block1(void *packet, uint32_t num, uint8_t more,
uint16_t size);
int coap_get_header_size2(void *packet, uint32_t *size);
int coap_set_header_size2(void *packet, uint32_t size);
int coap_get_header_size1(void *packet, uint32_t *size);
int coap_set_header_size1(void *packet, uint32_t size);
int coap_get_payload(void *packet, const uint8_t **payload);
int coap_set_payload(void *packet, const void *payload, size_t length);
#ifdef __cplusplus
}
#endif
#endif /* ER_COAP_H_ */

View File

@ -1,4 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
obj-y += coap_over_tcp.o

View File

@ -1,94 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "coap_ext.h"
char * coap_get_full_url_alloc(coap_packet_t * request)
{
const char *url = NULL;
const char * query = NULL;
int url_len = coap_get_header_uri_path(request, &url);
int query_len = coap_get_header_uri_query(request, &query);
if (url_len == 0)
return NULL;
char * url_alloc = (char*) bh_malloc(url_len + 1 + query_len + 1);
memcpy(url_alloc, url, url_len);
url_alloc[url_len] = 0;
// make the url looks like /abc?e=f
if (query_len != 0) {
strcat(url_alloc, "&");
memcpy(url_alloc + strlen(url_alloc), query, query_len);
url_alloc[url_len + 1 + query_len] = 0;
}
return url_alloc;
}
void convert_request_to_coap_packet(request_t * req, coap_packet_t * packet)
{
coap_init_message(packet, COAP_TYPE_NON, req->action, req->mid);
coap_set_token(packet, (uint8_t *) &req->mid, sizeof(req->mid));
coap_set_header_content_format(packet, req->fmt);
coap_set_header_uri_path(packet, req->url);
coap_set_payload(packet, req->payload, req->payload_len);
packet->mid = req->mid;
}
void convert_response_to_coap_packet(response_t * response,
coap_packet_t * packet)
{
coap_init_message(packet, COAP_TYPE_NON, response->status, response->mid);
coap_set_token(packet, (uint8_t *) &response->mid, sizeof(response->mid));
coap_set_header_content_format(packet, response->fmt);
coap_set_payload(packet, response->payload, response->payload_len);
packet->mid = response->mid;
}
// return: the length of url.
// note: the url is probably not end with 0 due to coap packing design.
int convert_coap_packet_to_request(coap_packet_t *packet, request_t *request)
{
const char *url = NULL;
int url_len = coap_get_header_uri_path(packet, &url);
memset(request, 0, sizeof(*request));
request->action = packet->code;
request->fmt = packet->content_format;
if (packet->token_len == 4) {
request->mid = *((unsigned long *) packet->token);
} else {
request->mid = packet->mid;
}
request->payload = packet->payload;
request->payload_len = packet->payload_len;
request->url = (char *)url;
return url_len;
}
void convert_coap_packet_to_response(coap_packet_t *packet,
response_t *response)
{
memset(response, 0, sizeof(*response));
response->status = packet->code;
response->fmt = packet->content_format;
if (packet->token_len == 4) {
response->mid = *((unsigned long *) packet->token);
} else {
response->mid = packet->mid;
}
response->payload = packet->payload;
response->payload_len = packet->payload_len;
return;
}

28
core/shared-lib/coap/extension/coap_ext.h Executable file → Normal file
View File

@ -6,8 +6,7 @@
#ifndef COAP_EXTENSION_COAP_EXT_H_ #ifndef COAP_EXTENSION_COAP_EXT_H_
#define COAP_EXTENSION_COAP_EXT_H_ #define COAP_EXTENSION_COAP_EXT_H_
#include "er-coap.h" #include "coap-constants.h"
#include "shared_utils.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -15,31 +14,6 @@ extern "C" {
#define COAP_EVENT (COAP_DELETE + 2) #define COAP_EVENT (COAP_DELETE + 2)
char * coap_get_full_url_alloc(coap_packet_t * request);
coap_status_t coap_parse_message_tcp(void *packet, uint8_t *data,
uint32_t data_len);
int coap_serialize_message_tcp(void *packet, uint8_t ** buffer_out);
int coap_set_payload_tcp(void *packet, const void *payload, size_t length);
uint8_t coap_is_request(coap_packet_t * coap_message);
uint16_t coap_find_mid(uint8_t *buffer);
uint8_t coap_find_code(uint8_t *buffer);
void coap_change_mid(uint8_t *buffer, uint16_t id);
int add_resource_handler(coap_context_t * coap_ctx,
coap_resource_handler_t * handler);
uint32_t check_blockwise_timeout_ms(coap_context_t * coap_ctx, int timeout_sec);
int convert_coap_packet_to_request(coap_packet_t *packet, request_t *request);
void convert_coap_packet_to_response(coap_packet_t *packet,
response_t *response);
void convert_response_to_coap_packet(response_t * response,
coap_packet_t * packet);
void convert_request_to_coap_packet(request_t * req, coap_packet_t * packet);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,470 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <string.h>
#include <stdio.h>
#include "bh_common.h"
#include "er-coap.h"
#include "coap_ext.h"
#include "er-coap-constants.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
#else
#define PRINTF(...)
#define PRINT6ADDR(addr)
#define PRINTLLADDR(addr)
#endif
extern size_t
coap_serialize_array_option(unsigned int number, unsigned int current_number,
uint8_t *buffer, uint8_t *array, size_t length, char split_char);
extern size_t
coap_serialize_int_option(unsigned int number, unsigned int current_number,
uint8_t *buffer, uint32_t value);
extern uint16_t coap_log_2(uint16_t value);
extern uint32_t coap_parse_int_option(uint8_t *bytes, size_t length);
extern void
coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option,
size_t option_len, char separator);
/*
*
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Len=15 | TKL | Extended Length (32 bits)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | Code | Token (if any, TKL bytes) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1| Payload (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
int coap_set_payload_tcp(void *packet, const void *payload, size_t length)
{
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
coap_pkt->payload = (uint8_t *) payload;
coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length);
return coap_pkt->payload_len;
}
#if 0
static size_t coap_calc_ext_len_field(int len)
{
if(len < 13)
return 0;
else if(len <= (0xFF+13))
return 1;
else if(len <= (0xFFFF+269))
return 2;
else if(len < (0xFFFFFFFF+65805))
return 4;
else
return 0;
}
#endif
static size_t coap_max_options_offset(void *packet)
{
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
return 6 + coap_pkt->token_len;
}
int coap_serialize_message_tcp(void *packet, uint8_t ** buffer_out)
{
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
uint8_t buffer[128];
uint8_t *option = buffer;
unsigned int current_number = 0;
if (coap_pkt->uri_path_len > 100) {
*buffer_out = 0;
return -1;
}
/* Serialize options */
current_number = 0;
if (0 == coap_pkt->token_len) {
bh_memcpy_s(coap_pkt->token, COAP_TOKEN_LEN, &coap_pkt->mid,
sizeof(coap_pkt->mid));
coap_pkt->token_len = sizeof(coap_pkt->mid);
}PRINTF("-Serializing options at %p-\n", option);
/* The options must be serialized in the order of their number */
COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match, "If-Match");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host, '\0',
"Uri-Host");
COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag, "ETag");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH,
content_format - coap_pkt-> content_format /* hack to get a zero field */,
"If-None-Match");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe, "Observe");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port, "Uri-Port");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path, '/',
"Location-Path");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path, 0, //'/',
"Uri-Path");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format,
"Content-Format");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age, "Max-Age");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query, '&',
"Uri-Query");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT, accept, "Accept");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query,
'&', "Location-Query");
COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2, "Block2");
COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1, "Block1");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2, "Size2");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri, '\0',
"Proxy-Uri");
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme, '\0',
"Proxy-Scheme");
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1, "Size1");
/* Pack payload */
if (coap_pkt->payload_len) {
*option = 0xFF;
++option;
}
uint32_t option_len = option - &buffer[0];
uint8_t * p = (uint8_t *) os_malloc(
coap_max_options_offset(packet) + option_len
+ coap_pkt->payload_len);
if (p == NULL)
return 0;
*buffer_out = p;
uint8_t first_4bits;
*p = (coap_pkt->token_len & 0xF);
uint32_t len = option_len + coap_pkt->payload_len;
if (len < 13) {
first_4bits = len;
*p++ |= first_4bits << 4;
} else if (len <= (0xFF + 13)) {
first_4bits = 13;
*p++ |= first_4bits << 4;
*p++ = len - 13;
} else if (len <= (0xFFFF + 269)) {
first_4bits = 14;
*p++ |= first_4bits << 4;
len -= 269;
*p = (uint8_t)(len >> 8);
p++;
*p = (uint8_t)(len & 0xFF);
p++;
} else {
first_4bits = 15;
*p++ |= first_4bits << 4;
len -= 65805;
*p++ = (uint8_t)(len >> 24);
*p++ = (uint8_t)(len >> 16);
*p++ = (uint8_t)(len >> 8);
*p++ = (uint8_t)(len & 0xFF);
}
*p = coap_pkt->code;
p++;
if (coap_pkt->token_len)
bh_memcpy_s(p, coap_pkt->token_len, coap_pkt->token,
coap_pkt->token_len);
p += coap_pkt->token_len;
bh_memcpy_s(p, option_len, buffer, option_len);
p += option_len;
bh_memcpy_s(p, coap_pkt->payload_len, coap_pkt->payload,
coap_pkt->payload_len);
p += coap_pkt->payload_len;
return (p - *buffer_out); /* packet length */
}
coap_status_t coap_parse_message_tcp(void *packet, uint8_t *data,
uint32_t data_len)
{
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
/* initialize packet */
memset(coap_pkt, 0, sizeof(coap_packet_t));
/* pointer to packet bytes */
coap_pkt->buffer = data;
/* parse header fields */
coap_pkt->version = 1;
coap_pkt->type = COAP_TYPE_NON;
coap_pkt->token_len = MIN(COAP_TOKEN_LEN, data[0] & 0xF);
coap_pkt->mid = 0;
uint8_t *p = data;
uint8_t first_4bits = data[0] >> 4;
uint32_t options_payload_size;
uint8_t ext_len_field = 0;
if (first_4bits < 13) {
options_payload_size = first_4bits;
p++;
} else if (first_4bits == 13) {
ext_len_field = 1;
options_payload_size = data[1] + 13;
p += 2;
} else if (first_4bits == 14) {
ext_len_field = 2;
options_payload_size = (uint16_t)(data[1] << 8) + data[2] + 269;
p += 3;
} else if (first_4bits == 15) {
ext_len_field = 4;
options_payload_size = (data[1] << 24) + (data[2] << 16)
+ (data[3] << 8) + data[4] + 65805;
p += 5;
}
// check the data size is smaller than the size indicated by the packet
if (ext_len_field + coap_pkt->token_len + 2 + options_payload_size
> data_len)
return BAD_REQUEST_4_00;
coap_pkt->code = *p++;
if (coap_pkt->token_len)
bh_memcpy_s(coap_pkt->token, COAP_TOKEN_LEN, p, coap_pkt->token_len);
if (coap_pkt->token_len >= 2) {
union {
uint16_t *mid;
uint8_t *token;
} mid_token_union;
mid_token_union.token = coap_pkt->token;
coap_pkt->mid = *(mid_token_union.mid);
}
p += coap_pkt->token_len;
uint8_t *current_option = p;
uint8_t * option_start = p;
/* parse options */
memset(coap_pkt->options, 0, sizeof(coap_pkt->options));
unsigned int option_number = 0;
unsigned int option_delta = 0;
size_t option_length = 0;
while (current_option < data + data_len) {
/* payload marker 0xFF, currently only checking for 0xF* because rest is reserved */
if ((current_option[0] & 0xF0) == 0xF0) {
coap_pkt->payload = ++current_option;
coap_pkt->payload_len = options_payload_size
- (coap_pkt->payload - option_start);
//coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
break;
}
option_delta = current_option[0] >> 4;
option_length = current_option[0] & 0x0F;
++current_option;
/* avoids code duplication without function overhead */
unsigned int *x = &option_delta;
do {
if (*x == 13) {
*x += current_option[0];
++current_option;
} else if (*x == 14) {
*x += 255;
*x += current_option[0] << 8;
++current_option;
*x += current_option[0];
++current_option;
}
} while (x != (unsigned int*) &option_length && (x =
(unsigned int*) &option_length));
option_length = *x;
option_number += option_delta;
PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta,
option_length);
SET_OPTION(coap_pkt, option_number);
switch (option_number) {
case COAP_OPTION_CONTENT_FORMAT:
coap_pkt->content_format = coap_parse_int_option(current_option,
option_length);
PRINTF("Content-Format [%u]\n", coap_pkt->content_format);
break;
case COAP_OPTION_MAX_AGE:
coap_pkt->max_age = coap_parse_int_option(current_option,
option_length);
PRINTF("Max-Age [%lu]\n", coap_pkt->max_age);
break;
case COAP_OPTION_ETAG:
coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length);
bh_memcpy_s(coap_pkt->etag, COAP_ETAG_LEN, current_option,
coap_pkt->etag_len);
PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1],
coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4],
coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7]
); /*FIXME always prints 8 bytes */
break;
case COAP_OPTION_ACCEPT:
coap_pkt->accept = coap_parse_int_option(current_option,
option_length);
PRINTF("Accept [%u]\n", coap_pkt->accept);
break;
case COAP_OPTION_IF_MATCH:
/* TODO support multiple ETags */
coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length);
bh_memcpy_s(coap_pkt->if_match, COAP_ETAG_LEN, current_option,
coap_pkt->if_match_len);
PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
coap_pkt->if_match_len, coap_pkt->if_match[0],
coap_pkt->if_match[1], coap_pkt->if_match[2],
coap_pkt->if_match[3], coap_pkt->if_match[4],
coap_pkt->if_match[5], coap_pkt->if_match[6],
coap_pkt->if_match[7]
); /* FIXME always prints 8 bytes */
break;
case COAP_OPTION_IF_NONE_MATCH:
coap_pkt->if_none_match = 1;
PRINTF("If-None-Match\n");
break;
case COAP_OPTION_PROXY_URI:
#if COAP_PROXY_OPTION_PROCESSING
coap_pkt->proxy_uri = (char *)current_option;
coap_pkt->proxy_uri_len = option_length;
#endif
PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len,
coap_pkt->proxy_uri);
coap_error_message = "This is a constrained server (Contiki)";
return PROXYING_NOT_SUPPORTED_5_05;
break;
case COAP_OPTION_PROXY_SCHEME:
#if COAP_PROXY_OPTION_PROCESSING
coap_pkt->proxy_scheme = (char *)current_option;
coap_pkt->proxy_scheme_len = option_length;
#endif
PRINTF("Proxy-Scheme NOT IMPLEMENTED [%.*s]\n",
coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme);
coap_error_message = "This is a constrained server (Contiki)";
return PROXYING_NOT_SUPPORTED_5_05;
break;
case COAP_OPTION_URI_HOST:
coap_pkt->uri_host = (char *) current_option;
coap_pkt->uri_host_len = option_length;
PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host);
break;
case COAP_OPTION_URI_PORT:
coap_pkt->uri_port = coap_parse_int_option(current_option,
option_length);
PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port);
break;
case COAP_OPTION_URI_PATH:
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
coap_merge_multi_option((char **) &(coap_pkt->uri_path),
&(coap_pkt->uri_path_len), current_option, option_length,
'/');
PRINTF("Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path);
break;
case COAP_OPTION_URI_QUERY:
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
coap_merge_multi_option((char **) &(coap_pkt->uri_query),
&(coap_pkt->uri_query_len), current_option, option_length,
'&');
PRINTF("Uri-Query [%.*s]\n", coap_pkt->uri_query_len,
coap_pkt->uri_query);
break;
case COAP_OPTION_LOCATION_PATH:
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
coap_merge_multi_option((char **) &(coap_pkt->location_path),
&(coap_pkt->location_path_len), current_option,
option_length, '/');
PRINTF("Location-Path [%.*s]\n", coap_pkt->location_path_len,
coap_pkt->location_path);
break;
case COAP_OPTION_LOCATION_QUERY:
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
coap_merge_multi_option((char **) &(coap_pkt->location_query),
&(coap_pkt->location_query_len), current_option,
option_length, '&');
PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len,
coap_pkt->location_query);
break;
case COAP_OPTION_OBSERVE:
coap_pkt->observe = coap_parse_int_option(current_option,
option_length);
PRINTF("Observe [%lu]\n", coap_pkt->observe);
break;
case COAP_OPTION_BLOCK2:
coap_pkt->block2_num = coap_parse_int_option(current_option,
option_length);
coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3;
coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)
<< (coap_pkt->block2_num & 0x07);
coap_pkt->block2_num >>= 4;
PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num,
coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size);
break;
case COAP_OPTION_BLOCK1:
coap_pkt->block1_num = coap_parse_int_option(current_option,
option_length);
coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3;
coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)
<< (coap_pkt->block1_num & 0x07);
coap_pkt->block1_num >>= 4;
PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num,
coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size);
break;
case COAP_OPTION_SIZE2:
coap_pkt->size2 = coap_parse_int_option(current_option,
option_length);
PRINTF("Size2 [%lu]\n", coap_pkt->size2);
break;
case COAP_OPTION_SIZE1:
coap_pkt->size1 = coap_parse_int_option(current_option,
option_length);
PRINTF("Size1 [%lu]\n", coap_pkt->size1);
break;
default:
PRINTF("unknown (%u)\n", option_number);
/* check if critical (odd) */
if (option_number & 1) {
coap_error_message = "Unsupported critical option";
return BAD_OPTION_4_02;
}
}
current_option += option_length;
} /* for */
PRINTF("-Done parsing-------\n");
return NO_ERROR;
}

View File

@ -1,78 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef COAP_PLATFORMS_H_
#define COAP_PLATFORMS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_platform.h"
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
/*#include "list_coap.h"*/
#include <stdbool.h>
#define COAP_TRANS_LOCK(ctx) coap_lock(ctx->transaction_lock)
#define COAP_TRANS_UNLOCK(ctx ) coap_unlock(ctx->transaction_lock)
/* REST_MAX_CHUNK_SIZE is the max size of payload.
* The maximum buffer size that is provided for resource responses and must be respected due to the limited IP buffer.
* Larger data must be handled by the resource and will be sent chunk-wise through a TCP stream or CoAP blocks.
*/
#ifndef REST_MAX_CHUNK_SIZE
#define REST_MAX_CHUNK_SIZE (1024*1024)
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif /* MIN */
#define CLOCK_SECOND 1000
typedef enum {
A_Raw, A_Sock_Addr, A_IP_Addr, A_Custom
} Net_Addr_Type;
#define NET_ADDR_RAW_SIZE 32
typedef struct net_addr_coap {
Net_Addr_Type addr_type;
union {
char raw[NET_ADDR_RAW_SIZE];
struct sockaddr_in sock_addr;
} u;
uint16_t port;
uint16_t addr_len;
} net_addr_t;
#define uip_ipaddr_t struct net_addr_coap
#define memb_free(x, y) free(x)
void set_addr_ip(uip_ipaddr_t *, char * ip, int port);
uip_ipaddr_t * new_net_addr(Net_Addr_Type type);
void copy_net_addr(uip_ipaddr_t * dest, uip_ipaddr_t * src);
bool compare_net_addr(uip_ipaddr_t * dest, uip_ipaddr_t * src);
uint32_t get_elpased_ms(uint32_t * last_system_clock);
uint32_t get_platform_time();
uint32_t get_platform_time_sec();
void coap_sleep_ms(uint32_t ms);
void coap_lock(void *);
void coap_unlock(void *);
void * coap_create_lock();
void coap_free_lock(void *);
void *xalloc(uint32_t size);
#define os_malloc bh_malloc
#define os_free bh_free
#ifdef __cplusplus
}
#endif
#endif /* COAP_PLATFORMS_H_ */

View File

@ -8,7 +8,6 @@
#include "bh_assert.h" #include "bh_assert.h"
#include "bh_platform.h" #include "bh_platform.h"
#include "bh_log.h"
#include "bh_list.h" #include "bh_list.h"
typedef void (*bh_print_function_t)(const char* message); typedef void (*bh_print_function_t)(const char* message);

View File

@ -45,7 +45,7 @@ void bh_memory_destroy();
* Get the pool size of memory, if memory is initialized with allocator, * Get the pool size of memory, if memory is initialized with allocator,
* return 1GB by default. * return 1GB by default.
*/ */
int bh_memory_pool_size(); unsigned bh_memory_pool_size();
#if BEIHAI_ENABLE_MEMORY_PROFILING == 0 #if BEIHAI_ENABLE_MEMORY_PROFILING == 0

View File

@ -54,7 +54,7 @@ void
bh_queue_destroy(bh_queue *queue); bh_queue_destroy(bh_queue *queue);
char * bh_message_payload(bh_message_t message); char * bh_message_payload(bh_message_t message);
int bh_message_payload_len(bh_message_t message); uint32 bh_message_payload_len(bh_message_t message);
int bh_message_type(bh_message_t message); int bh_message_type(bh_message_t message);
bh_message_t bh_new_msg(unsigned short tag, void *body, unsigned int len, bh_message_t bh_new_msg(unsigned short tag, void *body, unsigned int len,

View File

@ -95,7 +95,7 @@ void bh_memory_destroy()
memory_mode = MEMORY_MODE_UNKNOWN; memory_mode = MEMORY_MODE_UNKNOWN;
} }
int bh_memory_pool_size() unsigned bh_memory_pool_size()
{ {
if (memory_mode == MEMORY_MODE_POOL) if (memory_mode == MEMORY_MODE_POOL)
return global_pool_size; return global_pool_size;
@ -155,7 +155,7 @@ void* bh_malloc_profile(const char *file,
profile = bh_malloc_internal(sizeof(memory_profile_t)); profile = bh_malloc_internal(sizeof(memory_profile_t));
if (!profile) { if (!profile) {
vm_mutex_unlock(&profile_lock); vm_mutex_unlock(&profile_lock);
memcpy(p, &size, sizeof(size)); bh_memcpy_s(p, size + 8, &size, sizeof(size));
return (char *)p + 8; return (char *)p + 8;
} }
@ -171,7 +171,7 @@ void* bh_malloc_profile(const char *file,
vm_mutex_unlock(&profile_lock); vm_mutex_unlock(&profile_lock);
memcpy(p, &size, sizeof(size)); bh_memcpy_s(p, size + 8, &size, sizeof(size));
memory_in_use += size; memory_in_use += size;
memory_profile_print(file, line, func, size); memory_profile_print(file, line, func, size);

Some files were not shown because too many files have changed in this diff Show More