From b9d477248cf95f687654453d5cab8676789e6b0d Mon Sep 17 00:00:00 2001 From: Le Yao Date: Fri, 12 Mar 2021 14:16:00 +0800 Subject: [PATCH 01/19] Add wamr proxy-wasm header file The unique pointer to create wamr vm Signed-off-by: Le Yao --- include/proxy-wasm/wamr.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 include/proxy-wasm/wamr.h diff --git a/include/proxy-wasm/wamr.h b/include/proxy-wasm/wamr.h new file mode 100644 index 00000000..fcb14b73 --- /dev/null +++ b/include/proxy-wasm/wamr.h @@ -0,0 +1,26 @@ +// Copyright 2016-2019 Envoy Project Authors +// Copyright 2020 Google LLC +// +// 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. + +#pragma once + +#include + +#include "include/proxy-wasm/wasm_vm.h" + +namespace proxy_wasm { + +std::unique_ptr createWAMRVm(); + +} // namespace proxy_wasm From ce55a00d57ddd231fba0f419f5b4f0dad46868fe Mon Sep 17 00:00:00 2001 From: Le Yao Date: Mon, 15 Mar 2021 10:37:00 +0800 Subject: [PATCH 02/19] Add type convert for WAMR Types for webassembly micro runtime Signed-off-by: Le Yao --- src/wamr/types.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/wamr/types.h diff --git a/src/wamr/types.h b/src/wamr/types.h new file mode 100644 index 00000000..ab13872a --- /dev/null +++ b/src/wamr/types.h @@ -0,0 +1,45 @@ +// Copyright 2020 Google LLC +// +// 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. + +#include "src/common/types.h" +#include "wasm_c_api.h" + +namespace proxy_wasm { +namespace wamr { + +using WasmEnginePtr = common::CSmartPtr; +using WasmFuncPtr = common::CSmartPtr; +using WasmStorePtr = common::CSmartPtr; +using WasmModulePtr = common::CSmartPtr; +using WasmMemoryPtr = common::CSmartPtr; +using WasmTablePtr = common::CSmartPtr; +using WasmInstancePtr = common::CSmartPtr; +using WasmFunctypePtr = common::CSmartPtr; +using WasmTrapPtr = common::CSmartPtr; +using WasmExternPtr = common::CSmartPtr; + +using WasmByteVec = + common::CSmartType; +using WasmImporttypeVec = common::CSmartType; +using WasmExportTypeVec = common::CSmartType; +using WasmExternVec = + common::CSmartType; +using WasmValtypeVec = + common::CSmartType; + +} // namespace WAMR (webassembly micro runtime) + +} // namespace proxy_wasm From 2c3e791a6fed909e348fe73f5e804277a1076297 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Thu, 18 Mar 2021 01:47:33 +0000 Subject: [PATCH 03/19] Implement the proxy-wasm interface wasm_vm WAMR is commom WASM c/c++ API based, implenment same as wasitime Co-authored-by: Liang He Signed-off-by: Le Yao --- src/wamr/wamr.cc | 751 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 751 insertions(+) create mode 100644 src/wamr/wamr.cc diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc new file mode 100644 index 00000000..da438943 --- /dev/null +++ b/src/wamr/wamr.cc @@ -0,0 +1,751 @@ +// Copyright 2016-2019 Envoy Project Authors +// Copyright 2020 Google LLC +// +// 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. + +#include "include/proxy-wasm/wamr.h" +#include "include/proxy-wasm/wasm_vm.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/wamr/types.h" +#include "wasm_c_api.h" + +namespace proxy_wasm { +namespace wamr { + +struct HostFuncData { + HostFuncData(std::string name) : name_(std::move(name)) {} + + std::string name_; + WasmFuncPtr callback_; + void *raw_func_; + WasmVm *vm_; +}; + +using HostFuncDataPtr = std::unique_ptr; + +wasm_engine_t *engine() { + static const auto engine = WasmEnginePtr(wasm_engine_new()); + return engine.get(); +} + +class Wamr : public WasmVm { +public: + Wamr () {} + + std::string_view runtime() override { return "webassembly micro runtime"; } + std::string_view getPrecompiledSectionName() override { return ""; } + + Cloneable cloneable() override { return Cloneable::NotCloneable; } + std::unique_ptr clone() override { return nullptr; }; + + AbiVersion getAbiVersion() override; + std::string_view getCustomSection(std::string_view name) override; + + bool load(const std::string &code, bool allow_precompiled = false) override; + bool link(std::string_view debug_name) override; + uint64_t getMemorySize() override; + std::optional getMemory(uint64_t pointer, uint64_t size) override; + bool setMemory(uint64_t pointer, uint64_t size, const void *data) override; + bool getWord(uint64_t pointer, Word *word) override; + bool setWord(uint64_t pointer, Word word) override; + size_t getWordSize() override { return sizeof(uint32_t); }; + +#define _REGISTER_HOST_FUNCTION(T) \ + void registerCallback(std::string_view module_name, std::string_view function_name, T, \ + typename ConvertFunctionTypeWordToUint32::type f) override { \ + registerHostFunctionImpl(module_name, function_name, f); \ + }; + FOR_ALL_WASM_VM_IMPORTS(_REGISTER_HOST_FUNCTION) +#undef _REGISTER_HOST_FUNCTION + +#define _GET_MODULE_FUNCTION(T) \ + void getFunction(std::string_view function_name, T *f) override { \ + getModuleFunctionImpl(function_name, f); \ + }; + FOR_ALL_WASM_VM_EXPORTS(_GET_MODULE_FUNCTION) +#undef _GET_MODULE_FUNCTION +private: + bool getStrippedSource(WasmByteVec *out); + + template + void registerHostFunctionImpl(std::string_view module_name, std::string_view function_name, + void (*function)(void *, Args...)); + + template + void registerHostFunctionImpl(std::string_view module_name, std::string_view function_name, + R (*function)(void *, Args...)); + + template + void getModuleFunctionImpl(std::string_view function_name, + std::function *function); + + template + void getModuleFunctionImpl(std::string_view function_name, + std::function *function); + + WasmByteVec source_; + WasmStorePtr store_; + WasmModulePtr module_; + WasmInstancePtr instance_; + + WasmMemoryPtr memory_; + WasmTablePtr table_; + + std::unordered_map host_functions_; + std::unordered_map module_functions_; +}; + +// TODO(mathetake): move to proxy_wasm::common::* +static uint32_t parseVarint(const byte_t *&pos, const byte_t *end) { + uint32_t n = 0; + uint32_t shift = 0; + byte_t b; + do { + if (pos + 1 > end) { + abort(); + } + b = *pos++; + n += (b & 0x7f) << shift; + shift += 7; + } while ((b & 0x80) != 0); + return n; +} + +bool Wamr::load(const std::string &code, bool allow_precompiled) { + store_ = wasm_store_new(engine()); + + // Wasm file header is 8 bytes (magic number + version). + static const uint8_t magic_number[4] = {0x00, 0x61, 0x73, 0x6d}; + if (code.size() < 8 || ::memcmp(code.data(), magic_number, 4) != 0) { + return false; + } + + wasm_byte_vec_new_uninitialized(source_.get(), code.size()); + ::memcpy(source_.get()->data, code.data(), code.size()); + + WasmByteVec stripped; + module_ = + wasm_module_new(store_.get(), getStrippedSource(&stripped) ? stripped.get() : source_.get()); + + return module_ != nullptr; +} + +// TODO(mathetake): move to proxy_wasm::common::* +bool Wamr::getStrippedSource(WasmByteVec *out) { + std::vector stripped; + + const byte_t *pos = source_.get()->data + 8 /* Wasm header */; + const byte_t *end = source_.get()->data + source_.get()->size; + while (pos < end) { + const auto section_start = pos; + if (pos + 1 > end) { + return false; + } + const auto section_type = *pos++; + const auto section_len = parseVarint(pos, end); + if (section_len == static_cast(-1) || pos + section_len > end) { + return false; + } + if (section_type == 0 /* custom section */) { + const auto section_data_start = pos; + const auto section_name_len = parseVarint(pos, end); + if (section_name_len == static_cast(-1) || pos + section_name_len > end) { + return false; + } + auto section_name = std::string_view(pos, section_name_len); + if (section_name.find("precompiled_") != std::string::npos) { + // If this is the first "precompiled_" section, then save everything + // before it, otherwise skip it. + if (stripped.empty()) { + const byte_t *start = source_.get()->data; + stripped.insert(stripped.end(), start, section_start); + } + } + pos = section_data_start + section_len; + } else { + pos += section_len; + // Save this section if we already saw a custom "precompiled_" section. + if (!stripped.empty()) { + stripped.insert(stripped.end(), section_start, pos /* section end */); + } + } + } + + if (!stripped.empty()) { + wasm_byte_vec_new_uninitialized(out->get(), stripped.size()); + ::memcpy(out->get()->data, stripped.data(), stripped.size()); + return true; + } + return false; +} + +static bool equalValTypes(const wasm_valtype_vec_t *left, const wasm_valtype_vec_t *right) { + if (left->size != right->size) { + return false; + } + + for (size_t i = 0; i < left->size; i++) { + if (wasm_valtype_kind(left->data[i]) != wasm_valtype_kind(right->data[i])) { + return false; + } + } + + return true; +} + +static std::string printValue(const wasm_val_t &value) { + switch (value.kind) { + case WASM_I32: + return std::to_string(value.of.i32); + case WASM_I64: + return std::to_string(value.of.i64); + case WASM_F32: + return std::to_string(value.of.f32); + case WASM_F64: + return std::to_string(value.of.f64); + default: + return "unknown"; + } +} + +static std::string printValues(const wasm_val_t values[], size_t size) { + if (size == 0) { + return ""; + } + + std::string s; + for (size_t i = 0; i < size; i++) { + if (i) { + s.append(", "); + } + s.append(printValue(values[i])); + } + return s; +} + +static const char *printValKind(wasm_valkind_t kind) { + switch (kind) { + case WASM_I32: + return "i32"; + case WASM_I64: + return "i64"; + case WASM_F32: + return "f32"; + case WASM_F64: + return "f64"; + case WASM_ANYREF: + return "anyref"; + case WASM_FUNCREF: + return "funcref"; + default: + return "unknown"; + } +} + +static std::string printValTypes(const wasm_valtype_vec_t *types) { + if (types->size == 0) { + return "void"; + } + + std::string s; + s.reserve(types->size * 8 /* max size + " " */ - 1); + for (size_t i = 0; i < types->size; i++) { + if (i) { + s.append(" "); + } + s.append(printValKind(wasm_valtype_kind(types->data[i]))); + } + return s; +} + +bool Wamr::link(std::string_view debug_name) { + assert(module_ != nullptr); + + WasmImporttypeVec import_types; + wasm_module_imports(module_.get(), import_types.get()); + + std::vector imports; + for (size_t i = 0; i < import_types.get()->size; i++) { + const wasm_name_t *module_name_ptr = wasm_importtype_module(import_types.get()->data[i]); + const wasm_name_t *name_ptr = wasm_importtype_name(import_types.get()->data[i]); + const wasm_externtype_t *extern_type = wasm_importtype_type(import_types.get()->data[i]); + + std::string_view module_name(module_name_ptr->data, module_name_ptr->size); + std::string_view name(name_ptr->data, name_ptr->size); + assert(name_ptr->size > 0); + switch (wasm_externtype_kind(extern_type)) { + case WASM_EXTERN_FUNC: { + auto it = host_functions_.find(std::string(module_name) + "." + std::string(name)); + if (it == host_functions_.end()) { + fail(FailState::UnableToInitializeCode, + std::string("Failed to load Wasm module due to a missing import: ") + + std::string(module_name) + "." + std::string(name)); + break; + } + + auto func = it->second->callback_.get(); + const wasm_functype_t *exp_type = wasm_externtype_as_functype_const(extern_type); + WasmFunctypePtr actual_type = wasm_func_type(it->second->callback_.get()); + if (!equalValTypes(wasm_functype_params(exp_type), wasm_functype_params(actual_type.get())) || + !equalValTypes(wasm_functype_results(exp_type), + wasm_functype_results(actual_type.get()))) { + fail( + FailState::UnableToInitializeCode, + std::string("Failed to load Wasm module due to an import type mismatch for function ") + + std::string(module_name) + "." + std::string(name) + + ", want: " + printValTypes(wasm_functype_params(exp_type)) + " -> " + + printValTypes(wasm_functype_results(exp_type)) + + ", but host exports: " + printValTypes(wasm_functype_params(actual_type.get())) + + " -> " + printValTypes(wasm_functype_results(actual_type.get()))); + break; + } + imports.push_back(wasm_func_as_extern(func)); + } break; + case WASM_EXTERN_GLOBAL: { + // TODO(mathetake): add support when/if needed. + fail(FailState::UnableToInitializeCode, + "Failed to load Wasm module due to a missing import: " + std::string(module_name) + "." + + std::string(name)); + } break; + case WASM_EXTERN_MEMORY: { + assert(memory_ == nullptr); + const wasm_memorytype_t *memory_type = + wasm_externtype_as_memorytype_const(extern_type); // owned by `extern_type` + memory_ = wasm_memory_new(store_.get(), memory_type); + imports.push_back(wasm_memory_as_extern(memory_.get())); + } break; + case WASM_EXTERN_TABLE: { + assert(table_ == nullptr); + const wasm_tabletype_t *table_type = + wasm_externtype_as_tabletype_const(extern_type); // owned by `extern_type` + table_ = wasm_table_new(store_.get(), table_type, nullptr); + imports.push_back(wasm_table_as_extern(table_.get())); + } break; + } + } + + if (import_types.get()->size != imports.size()) { + return false; + } + + instance_ = wasm_instance_new(store_.get(), module_.get(), imports.data(), nullptr); + assert(instance_ != nullptr); + + WasmExportTypeVec export_types; + wasm_module_exports(module_.get(), export_types.get()); + + WasmExternVec exports; + wasm_instance_exports(instance_.get(), exports.get()); + + for (size_t i = 0; i < export_types.get()->size; i++) { + const wasm_externtype_t *exp_extern_type = wasm_exporttype_type(export_types.get()->data[i]); + wasm_extern_t *actual_extern = exports.get()->data[i]; + + wasm_externkind_t kind = wasm_extern_kind(actual_extern); + assert(kind == wasm_externtype_kind(exp_extern_type)); + switch (kind) { + case WASM_EXTERN_FUNC: { + WasmFuncPtr func = wasm_func_copy(wasm_extern_as_func(actual_extern)); + const wasm_name_t *name_ptr = wasm_exporttype_name(export_types.get()->data[i]); + module_functions_.insert_or_assign(std::string(name_ptr->data, name_ptr->size), + std::move(func)); + } break; + case WASM_EXTERN_GLOBAL: { + // TODO(mathetake): add support when/if needed. + } break; + case WASM_EXTERN_MEMORY: { + assert(memory_ == nullptr); + memory_ = wasm_memory_copy(wasm_extern_as_memory(actual_extern)); + assert(memory_ != nullptr); + } break; + case WASM_EXTERN_TABLE: { + // TODO(mathetake): add support when/if needed. + } break; + } + } + return true; +} + +std::string_view Wamr::getCustomSection(std::string_view name) { + const byte_t *pos = source_.get()->data + 8 /* Wasm header */; + const byte_t *end = source_.get()->data + source_.get()->size; + while (pos < end) { + if (pos + 1 > end) { + fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); + return ""; + } + const auto section_type = *pos++; + const auto section_len = parseVarint(pos, end); + if (section_len == static_cast(-1) || pos + section_len > end) { + fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); + return ""; + } + + if (section_type == 0 /* custom section */) { + const auto section_data_start = pos; + const auto section_name_len = parseVarint(pos, end); + if (section_name_len == static_cast(-1) || pos + section_name_len > end) { + fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); + return ""; + } + if (section_name_len == name.size() && ::memcmp(pos, name.data(), section_name_len) == 0) { + pos += section_name_len; + return {pos, static_cast(section_data_start + section_len - pos)}; + } + pos = section_data_start + section_len; + } else { + pos += section_len; + } + } + + return ""; +} + +uint64_t Wamr::getMemorySize() { return wasm_memory_data_size(memory_.get()); } + +std::optional Wamr::getMemory(uint64_t pointer, uint64_t size) { + assert(memory_ != nullptr); + if (pointer + size > wasm_memory_data_size(memory_.get())) { + return std::nullopt; + } + return std::string_view(wasm_memory_data(memory_.get()) + pointer, size); +} + +bool Wamr::setMemory(uint64_t pointer, uint64_t size, const void *data) { + assert(memory_ != nullptr); + if (pointer + size > wasm_memory_data_size(memory_.get())) { + return false; + } + ::memcpy(wasm_memory_data(memory_.get()) + pointer, data, size); + return true; +} + +bool Wamr::getWord(uint64_t pointer, Word *word) { + assert(memory_ != nullptr); + constexpr auto size = sizeof(uint32_t); + if (pointer + size > wasm_memory_data_size(memory_.get())) { + return false; + } + + uint32_t word32; + ::memcpy(&word32, wasm_memory_data(memory_.get()) + pointer, size); + word->u64_ = word32; + return true; +} + +bool Wamr::setWord(uint64_t pointer, Word word) { + constexpr auto size = sizeof(uint32_t); + if (pointer + size > wasm_memory_data_size(memory_.get())) { + return false; + } + uint32_t word32 = word.u32(); + ::memcpy(wasm_memory_data(memory_.get()) + pointer, &word32, size); + return true; +} + +template void assignVal(T t, wasm_val_t &val); +template <> void assignVal(Word t, wasm_val_t &val) { + val.kind = WASM_I32; + val.of.i32 = static_cast(t.u64_); +} +template <> void assignVal(uint32_t t, wasm_val_t &val) { + val.kind = WASM_I32; + val.of.i32 = static_cast(t); +} +template <> void assignVal(uint64_t t, wasm_val_t &val) { + val.kind = WASM_I64; + val.of.i64 = static_cast(t); +} +template <> void assignVal(double t, wasm_val_t &val) { + val.kind = WASM_F64; + val.of.f64 = t; +} + +template wasm_val_t makeVal(T t) { + wasm_val_t val{}; + assignVal(t, val); + return val; +} + +template struct ConvertWordType { + using type = T; // NOLINT(readability-identifier-naming) +}; +template <> struct ConvertWordType { + using type = uint32_t; // NOLINT(readability-identifier-naming) +}; + +template auto convertArgToValTypePtr(); +template <> auto convertArgToValTypePtr() { return wasm_valtype_new_i32(); }; +template <> auto convertArgToValTypePtr() { return wasm_valtype_new_i32(); }; +template <> auto convertArgToValTypePtr() { return wasm_valtype_new_i64(); }; +template <> auto convertArgToValTypePtr() { return wasm_valtype_new_i64(); }; +template <> auto convertArgToValTypePtr() { return wasm_valtype_new_f64(); }; + +template T convertValueTypeToArg(wasm_val_t val); +template <> uint32_t convertValueTypeToArg(wasm_val_t val) { + return static_cast(val.of.i32); +} +template <> Word convertValueTypeToArg(wasm_val_t val) { return val.of.i32; } +template <> int64_t convertValueTypeToArg(wasm_val_t val) { return val.of.i64; } +template <> uint64_t convertValueTypeToArg(wasm_val_t val) { + return static_cast(val.of.i64); +} +template <> double convertValueTypeToArg(wasm_val_t val) { return val.of.f64; } + +template +constexpr T convertValTypesToArgsTupleImpl(const U &arr, std::index_sequence) { + return std::make_tuple( + convertValueTypeToArg>::type>(arr[I])...); +} + +template ::value>> +constexpr T convertValTypesToArgsTuple(const U &arr) { + return convertValTypesToArgsTupleImpl(arr, Is()); +} + +template +void convertArgsTupleToValTypesImpl(wasm_valtype_vec_t *types, std::index_sequence) { + auto size = std::tuple_size::value; + auto ps = std::array::value>{ + convertArgToValTypePtr::type>()...}; + wasm_valtype_vec_new(types, size, ps.data()); + for (auto i = ps.begin(); i < ps.end(); i++) { // TODO(mathetake): better way to handle? + wasm_valtype_delete(*i); + } +} + +template ::value>> +void convertArgsTupleToValTypes(wasm_valtype_vec_t *types) { + convertArgsTupleToValTypesImpl(types, Is()); +} + +template WasmFunctypePtr newWasmNewFuncType() { + WasmValtypeVec params, results; + convertArgsTupleToValTypes(params.get()); + convertArgsTupleToValTypes>(results.get()); + return wasm_functype_new(params.get(), results.get()); +} + +template WasmFunctypePtr newWasmNewFuncType() { + WasmValtypeVec params, results; + convertArgsTupleToValTypes(params.get()); + convertArgsTupleToValTypes>(results.get()); + return wasm_functype_new(params.get(), results.get()); +} + +template +void Wamr::registerHostFunctionImpl(std::string_view module_name, + std::string_view function_name, + void (*function)(void *, Args...)) { + auto data = + std::make_unique(std::string(module_name) + "." + std::string(function_name)); + + WasmFunctypePtr type = newWasmNewFuncType>(); + WasmFuncPtr func = wasm_func_new_with_env( + store_.get(), type.get(), + [](void *data, const wasm_val_t params[], wasm_val_t results[]) -> wasm_trap_t * { + auto func_data = reinterpret_cast(data); + if (func_data->vm_->cmpLogLevel(LogLevel::trace)) { + func_data->vm_->integration()->trace("[vm->host] " + func_data->name_ + "(" + + printValues(params, sizeof...(Args)) + ")"); + } + auto args_tuple = convertValTypesToArgsTuple>(params); + auto args = std::tuple_cat(std::make_tuple(current_context_), args_tuple); + auto fn = reinterpret_cast(func_data->raw_func_); + std::apply(fn, args); + if (func_data->vm_->cmpLogLevel(LogLevel::trace)) { + func_data->vm_->integration()->trace("[vm<-host] " + func_data->name_ + " return: void"); + } + return nullptr; + }, + data.get(), nullptr); + + data->vm_ = this; + data->callback_ = std::move(func); + data->raw_func_ = reinterpret_cast(function); + host_functions_.insert_or_assign(std::string(module_name) + "." + std::string(function_name), + std::move(data)); +}; + +template +void Wamr::registerHostFunctionImpl(std::string_view module_name, + std::string_view function_name, + R (*function)(void *, Args...)) { + auto data = + std::make_unique(std::string(module_name) + "." + std::string(function_name)); + WasmFunctypePtr type = newWasmNewFuncType>(); + WasmFuncPtr func = wasm_func_new_with_env( + store_.get(), type.get(), + [](void *data, const wasm_val_t params[], wasm_val_t results[]) -> wasm_trap_t * { + auto func_data = reinterpret_cast(data); + if (func_data->vm_->cmpLogLevel(LogLevel::trace)) { + func_data->vm_->integration()->trace("[vm->host] " + func_data->name_ + "(" + + printValues(params, sizeof...(Args)) + ")"); + } + auto args_tuple = convertValTypesToArgsTuple>(params); + auto args = std::tuple_cat(std::make_tuple(current_context_), args_tuple); + auto fn = reinterpret_cast(func_data->raw_func_); + R res = std::apply(fn, args); + assignVal(res, results[0]); + if (func_data->vm_->cmpLogLevel(LogLevel::trace)) { + func_data->vm_->integration()->trace("[vm<-host] " + func_data->name_ + + " return: " + std::to_string(res)); + } + return nullptr; + }, + data.get(), nullptr); + + data->vm_ = this; + data->callback_ = std::move(func); + data->raw_func_ = reinterpret_cast(function); + host_functions_.insert_or_assign(std::string(module_name) + "." + std::string(function_name), + std::move(data)); +}; + +template +void Wamr::getModuleFunctionImpl(std::string_view function_name, + std::function *function) { + + auto it = module_functions_.find(std::string(function_name)); + if (it == module_functions_.end()) { + *function = nullptr; + return; + } + + WasmValtypeVec exp_args, exp_returns; + convertArgsTupleToValTypes>(exp_args.get()); + convertArgsTupleToValTypes>(exp_returns.get()); + wasm_func_t *func = it->second.get(); + WasmFunctypePtr func_type = wasm_func_type(func); + + if (!equalValTypes(wasm_functype_params(func_type.get()), exp_args.get()) || + !equalValTypes(wasm_functype_results(func_type.get()), exp_returns.get())) { + fail(FailState::UnableToInitializeCode, + "Bad function signature for: " + std::string(function_name) + ", want: " + + printValTypes(exp_args.get()) + " -> " + printValTypes(exp_returns.get()) + + ", but the module exports: " + printValTypes(wasm_functype_params(func_type.get())) + + " -> " + printValTypes(wasm_functype_results(func_type.get()))); + return; + } + + *function = [func, function_name, this](ContextBase *context, Args... args) -> void { + wasm_val_t params[] = {makeVal(args)...}; + SaveRestoreContext saved_context(context); + if (cmpLogLevel(LogLevel::trace)) { + integration()->trace("[host->vm] " + std::string(function_name) + "(" + + printValues(params, sizeof...(Args)) + ")"); + } + WasmTrapPtr trap{wasm_func_call(func, params, nullptr)}; + if (trap) { + WasmByteVec error_message; + wasm_trap_message(trap.get(), error_message.get()); + fail(FailState::RuntimeError, + "Function: " + std::string(function_name) + " failed:\n" + + std::string(error_message.get()->data, error_message.get()->size)); + return; + } + if (cmpLogLevel(LogLevel::trace)) { + integration()->trace("[host<-vm] " + std::string(function_name) + " return: void"); + } + }; +}; + +template +void Wamr::getModuleFunctionImpl(std::string_view function_name, + std::function *function) { + auto it = module_functions_.find(std::string(function_name)); + if (it == module_functions_.end()) { + *function = nullptr; + return; + } + WasmValtypeVec exp_args, exp_returns; + convertArgsTupleToValTypes>(exp_args.get()); + convertArgsTupleToValTypes>(exp_returns.get()); + wasm_func_t *func = it->second.get(); + WasmFunctypePtr func_type = wasm_func_type(func); + if (!equalValTypes(wasm_functype_params(func_type.get()), exp_args.get()) || + !equalValTypes(wasm_functype_results(func_type.get()), exp_returns.get())) { + fail(FailState::UnableToInitializeCode, + "Bad function signature for: " + std::string(function_name) + ", want: " + + printValTypes(exp_args.get()) + " -> " + printValTypes(exp_returns.get()) + + ", but the module exports: " + printValTypes(wasm_functype_params(func_type.get())) + + " -> " + printValTypes(wasm_functype_results(func_type.get()))); + return; + } + + *function = [func, function_name, this](ContextBase *context, Args... args) -> R { + wasm_val_t params[] = {makeVal(args)...}; + wasm_val_t results[1]; + SaveRestoreContext saved_context(context); + if (cmpLogLevel(LogLevel::trace)) { + integration()->trace("[host->vm] " + std::string(function_name) + "(" + + printValues(params, sizeof...(Args)) + ")"); + } + WasmTrapPtr trap{wasm_func_call(func, params, results)}; + if (trap) { + WasmByteVec error_message; + wasm_trap_message(trap.get(), error_message.get()); + fail(FailState::RuntimeError, + "Function: " + std::string(function_name) + " failed:\n" + + std::string(error_message.get()->data, error_message.get()->size)); + return R{}; + } + R ret = convertValueTypeToArg(results[0]); + if (cmpLogLevel(LogLevel::trace)) { + integration()->trace("[host<-vm] " + std::string(function_name) + + " return: " + std::to_string(ret)); + } + return ret; + }; +}; + +AbiVersion Wamr::getAbiVersion() { + assert(module_ != nullptr); + WasmExportTypeVec export_types; + wasm_module_exports(module_.get(), export_types.get()); + + for (size_t i = 0; i < export_types.get()->size; i++) { + const wasm_externtype_t *exp_extern_type = wasm_exporttype_type(export_types.get()->data[i]); + if (wasm_externtype_kind(exp_extern_type) == WASM_EXTERN_FUNC) { + const wasm_name_t *name_ptr = wasm_exporttype_name(export_types.get()->data[i]); + std::string_view name(name_ptr->data, name_ptr->size); + if (name == "proxy_abi_version_0_1_0") { + return AbiVersion::ProxyWasm_0_1_0; + } else if (name == "proxy_abi_version_0_2_0") { + return AbiVersion::ProxyWasm_0_2_0; + } else if (name == "proxy_abi_version_0_2_1") { + return AbiVersion::ProxyWasm_0_2_1; + } + } + } + return AbiVersion::Unknown; +} + +} // namespace wamr + +std::unique_ptr createWamrVm() { return std::make_unique(); } + +} // namespace proxy_wasm From 9724c9693c14a60bb785782f7ffa689e7aa416e0 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Fri, 19 Mar 2021 02:55:04 +0000 Subject: [PATCH 04/19] Bazel build the runtime from external WAMR repo Build and testing runtime Signed-off-by: Le Yao --- BUILD | 1 + bazel/external/wamr.BUILD | 24 ++++++++++++++++++++++++ bazel/repositories.bzl | 8 ++++++++ src/wamr/types.h | 2 +- src/wamr/wamr.cc | 2 +- test/utility.h | 3 +++ 6 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 bazel/external/wamr.BUILD diff --git a/BUILD b/BUILD index 840ccd3a..9e4e84f5 100644 --- a/BUILD +++ b/BUILD @@ -35,5 +35,6 @@ cc_library( "@com_google_protobuf//:protobuf_lite", "@proxy_wasm_cpp_sdk//:api_lib", "@wasm_c_api//:wasmtime_lib", + "@wamr//:wamr_lib", ], ) diff --git a/bazel/external/wamr.BUILD b/bazel/external/wamr.BUILD new file mode 100644 index 00000000..c173d506 --- /dev/null +++ b/bazel/external/wamr.BUILD @@ -0,0 +1,24 @@ +licenses(["notice"]) # Apache 2 + +package(default_visibility = ["//visibility:public"]) + +cc_import( + name = "linklib", + shared_library = "library/linux-classic_interp-multi_module-dbg/libiwasm.so", +) + +cc_library( + name = "headlib", + hdrs = glob(["include/*.h"]), + srcs = glob(["include/*.c"]), + include_prefix = "wamr", +) + +cc_library( + name = "wamr_lib", + defines = ["WASM_WAMR"], + deps = [ + "linklib", + "headlib", + ], +) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 28036849..a5d092f1 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -44,6 +44,14 @@ def proxy_wasm_cpp_host_repositories(): url = "https://github.com/bytecodealliance/wasmtime/archive/v0.26.0.tar.gz", ) + http_archive( + name = "wamr", + build_file = "@proxy_wasm_cpp_host//bazel/external:wamr.BUILD", + sha256 = "fb2ca3b0322becb8c62de626181ef66a7be15e36000913f0ad4bf51d4619891b", + strip_prefix = "wamr_pre_release", + url = "https://github.com/lum1n0us/wasm-micro-runtime/releases/download/WAMR-01-29-2021/wamr_pre_release.zip", + ) + http_archive( name = "wasm_c_api", build_file = "@proxy_wasm_cpp_host//bazel/external:wasm-c-api.BUILD", diff --git a/src/wamr/types.h b/src/wamr/types.h index ab13872a..1b06bf98 100644 --- a/src/wamr/types.h +++ b/src/wamr/types.h @@ -13,7 +13,7 @@ // limitations under the License. #include "src/common/types.h" -#include "wasm_c_api.h" +#include "wamr/include/wasm_c_api.h" namespace proxy_wasm { namespace wamr { diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index da438943..c5d9ecf1 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -30,7 +30,7 @@ #include #include "src/wamr/types.h" -#include "wasm_c_api.h" +#include "wamr/include/wasm_c_api.h" namespace proxy_wasm { namespace wamr { diff --git a/test/utility.h b/test/utility.h index 22a86f1f..635b396a 100644 --- a/test/utility.h +++ b/test/utility.h @@ -32,6 +32,9 @@ #if defined(WASM_WASMTIME) #include "include/proxy-wasm/wasmtime.h" #endif +#if defined(WASM_WASMTIME) +#include "include/proxy-wasm/wamr.h" +#endif namespace proxy_wasm { From ac6b4ad462c4e3c7f31df1ddb502b69502e4f5d9 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Fri, 19 Mar 2021 05:45:22 +0000 Subject: [PATCH 05/19] Format the c/c++ files and build files Signed-off-by: Le Yao --- BUILD | 2 +- src/wamr/types.h | 2 +- src/wamr/wamr.cc | 16 +++++++--------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/BUILD b/BUILD index 9e4e84f5..191f8dd3 100644 --- a/BUILD +++ b/BUILD @@ -34,7 +34,7 @@ cc_library( "@boringssl//:crypto", "@com_google_protobuf//:protobuf_lite", "@proxy_wasm_cpp_sdk//:api_lib", - "@wasm_c_api//:wasmtime_lib", "@wamr//:wamr_lib", + "@wasm_c_api//:wasmtime_lib", ], ) diff --git a/src/wamr/types.h b/src/wamr/types.h index 1b06bf98..34b8f41f 100644 --- a/src/wamr/types.h +++ b/src/wamr/types.h @@ -40,6 +40,6 @@ using WasmExternVec = using WasmValtypeVec = common::CSmartType; -} // namespace WAMR (webassembly micro runtime) +} // namespace wamr } // namespace proxy_wasm diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index c5d9ecf1..4772dd9c 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -53,7 +53,7 @@ wasm_engine_t *engine() { class Wamr : public WasmVm { public: - Wamr () {} + Wamr() {} std::string_view runtime() override { return "webassembly micro runtime"; } std::string_view getPrecompiledSectionName() override { return ""; } @@ -557,9 +557,8 @@ template WasmFunctypePtr newWasmNewFuncType() { } template -void Wamr::registerHostFunctionImpl(std::string_view module_name, - std::string_view function_name, - void (*function)(void *, Args...)) { +void Wamr::registerHostFunctionImpl(std::string_view module_name, std::string_view function_name, + void (*function)(void *, Args...)) { auto data = std::make_unique(std::string(module_name) + "." + std::string(function_name)); @@ -591,9 +590,8 @@ void Wamr::registerHostFunctionImpl(std::string_view module_name, }; template -void Wamr::registerHostFunctionImpl(std::string_view module_name, - std::string_view function_name, - R (*function)(void *, Args...)) { +void Wamr::registerHostFunctionImpl(std::string_view module_name, std::string_view function_name, + R (*function)(void *, Args...)) { auto data = std::make_unique(std::string(module_name) + "." + std::string(function_name)); WasmFunctypePtr type = newWasmNewFuncType>(); @@ -627,7 +625,7 @@ void Wamr::registerHostFunctionImpl(std::string_view module_name, template void Wamr::getModuleFunctionImpl(std::string_view function_name, - std::function *function) { + std::function *function) { auto it = module_functions_.find(std::string(function_name)); if (it == module_functions_.end()) { @@ -675,7 +673,7 @@ void Wamr::getModuleFunctionImpl(std::string_view function_name, template void Wamr::getModuleFunctionImpl(std::string_view function_name, - std::function *function) { + std::function *function) { auto it = module_functions_.find(std::string(function_name)); if (it == module_functions_.end()) { *function = nullptr; From 564b3c1342989a76e552719de35c14f398021335 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Thu, 25 Mar 2021 03:05:56 +0000 Subject: [PATCH 06/19] Fix symbol link error when testing runtime Add wamr runtime to testing, passed Signed-off-by: Le Yao --- include/proxy-wasm/wamr.h | 2 +- src/wamr/wamr.cc | 24 +++++++++++++++++++++--- test/utility.cc | 3 +++ test/utility.h | 6 +++++- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/include/proxy-wasm/wamr.h b/include/proxy-wasm/wamr.h index fcb14b73..98ff72e3 100644 --- a/include/proxy-wasm/wamr.h +++ b/include/proxy-wasm/wamr.h @@ -21,6 +21,6 @@ namespace proxy_wasm { -std::unique_ptr createWAMRVm(); +std::unique_ptr createWamrVm(); } // namespace proxy_wasm diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 4772dd9c..13ea2786 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -55,11 +55,14 @@ class Wamr : public WasmVm { public: Wamr() {} - std::string_view runtime() override { return "webassembly micro runtime"; } + std::string_view runtime() override { return "wamr"; } std::string_view getPrecompiledSectionName() override { return ""; } - Cloneable cloneable() override { return Cloneable::NotCloneable; } - std::unique_ptr clone() override { return nullptr; }; + Cloneable cloneable() override { + return Cloneable::CompiledBytecode; + ; + } + std::unique_ptr clone() override; AbiVersion getAbiVersion() override; std::string_view getCustomSection(std::string_view name) override; @@ -153,6 +156,21 @@ bool Wamr::load(const std::string &code, bool allow_precompiled) { return module_ != nullptr; } +std::unique_ptr Wamr::clone() { + assert(module_ != nullptr); + + auto clone = std::make_unique(); + + clone->integration().reset(integration()->clone()); + + clone->store_ = wasm_store_new(engine()); + + WasmByteVec stripped; + clone->module_ = + wasm_module_new(store_.get(), getStrippedSource(&stripped) ? stripped.get() : source_.get()); + return clone; +} + // TODO(mathetake): move to proxy_wasm::common::* bool Wamr::getStrippedSource(WasmByteVec *out) { std::vector stripped; diff --git a/test/utility.cc b/test/utility.cc index e55a5773..5b999c0c 100644 --- a/test/utility.cc +++ b/test/utility.cc @@ -26,6 +26,9 @@ std::vector getRuntimes() { #endif #if defined(WASM_WASMTIME) "wasmtime", +#endif +#if defined(WASM_WAMR) + "wamr", #endif "" }; diff --git a/test/utility.h b/test/utility.h index 635b396a..05ed1cf5 100644 --- a/test/utility.h +++ b/test/utility.h @@ -32,7 +32,7 @@ #if defined(WASM_WASMTIME) #include "include/proxy-wasm/wasmtime.h" #endif -#if defined(WASM_WASMTIME) +#if defined(WASM_WAMR) #include "include/proxy-wasm/wamr.h" #endif @@ -82,6 +82,10 @@ class TestVM : public testing::TestWithParam { #if defined(WASM_WASMTIME) } else if (runtime_ == "wasmtime") { vm_ = proxy_wasm::createWasmtimeVm(); +#endif +#if defined(WASM_WAMR) + } else if (runtime_ == "wamr") { + vm_ = proxy_wasm::createWamrVm(); #endif } vm_->integration().reset(integration_); From 3031f9af8545422ffdb4a22ebf3d409bc1066f63 Mon Sep 17 00:00:00 2001 From: liam Date: Wed, 31 Mar 2021 20:41:04 +0800 Subject: [PATCH 07/19] compile WAMR from source code using a pre-release archive until passing integration Signed-off-by: liam --- BUILD | 6 +++--- WORKSPACE | 4 ++++ bazel/external/wamr.BUILD | 36 ++++++++++++++++++------------------ bazel/repositories.bzl | 18 +++++++++++++++--- src/wamr/types.h | 2 +- src/wamr/wamr.cc | 5 ++--- 6 files changed, 43 insertions(+), 28 deletions(-) diff --git a/BUILD b/BUILD index 191f8dd3..e160ae48 100644 --- a/BUILD +++ b/BUILD @@ -23,8 +23,9 @@ cc_library( "src/**/*.h", ], exclude = [ - "src/**/wavm*", "src/**/v8*", + "src/**/wasmtime*", + "src/**/wavm*", ], ), hdrs = glob(["src/**/*.h"]), @@ -34,7 +35,6 @@ cc_library( "@boringssl//:crypto", "@com_google_protobuf//:protobuf_lite", "@proxy_wasm_cpp_sdk//:api_lib", - "@wamr//:wamr_lib", - "@wasm_c_api//:wasmtime_lib", + "@wamr//:libiwasm", ], ) diff --git a/WORKSPACE b/WORKSPACE index 77ecd3a0..48a10fb5 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -7,3 +7,7 @@ proxy_wasm_cpp_host_repositories() load("@proxy_wasm_cpp_host//bazel:dependencies.bzl", "proxy_wasm_cpp_host_dependencies") proxy_wasm_cpp_host_dependencies() + +load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies") + +rules_foreign_cc_dependencies() \ No newline at end of file diff --git a/bazel/external/wamr.BUILD b/bazel/external/wamr.BUILD index c173d506..32d20060 100644 --- a/bazel/external/wamr.BUILD +++ b/bazel/external/wamr.BUILD @@ -1,24 +1,24 @@ licenses(["notice"]) # Apache 2 -package(default_visibility = ["//visibility:public"]) +load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake") -cc_import( - name = "linklib", - shared_library = "library/linux-classic_interp-multi_module-dbg/libiwasm.so", -) +package(default_visibility = ["//visibility:public"]) -cc_library( - name = "headlib", - hdrs = glob(["include/*.h"]), - srcs = glob(["include/*.c"]), - include_prefix = "wamr", +filegroup( + name = "srcs", + srcs = glob(["**"]), + visibility = ["//visibility:public"], ) -cc_library( - name = "wamr_lib", - defines = ["WASM_WAMR"], - deps = [ - "linklib", - "headlib", - ], -) +cmake( + name = "libiwasm", + cache_entries = { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_EXPORT_COMPILE_COMMANDS": "On", + "WAMR_BUILD_AOT": "0", + "WAMR_BUILD_SIMD": "0", + }, + lib_source = ":srcs", + out_shared_libs = ["libiwasm.so"], + working_directory = "product-mini/platforms/linux" +) \ No newline at end of file diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index a5d092f1..8668d4a6 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -47,11 +47,16 @@ def proxy_wasm_cpp_host_repositories(): http_archive( name = "wamr", build_file = "@proxy_wasm_cpp_host//bazel/external:wamr.BUILD", - sha256 = "fb2ca3b0322becb8c62de626181ef66a7be15e36000913f0ad4bf51d4619891b", - strip_prefix = "wamr_pre_release", - url = "https://github.com/lum1n0us/wasm-micro-runtime/releases/download/WAMR-01-29-2021/wamr_pre_release.zip", + sha256 = "88cd7145d7098daacfb0da51548327f4e5303d17ea27611cde6f47c6f7b68059", + url = "https://github.com/lum1n0us/wasm-micro-runtime/releases/download/WAMR-01-29-2021/source.zip", ) + # native.new_local_repository( + # name = "wamr", + # build_file = "@proxy_wasm_cpp_host//bazel/external:wamr.BUILD", + # path = "/source/wamr", + # ) + http_archive( name = "wasm_c_api", build_file = "@proxy_wasm_cpp_host//bazel/external:wasm-c-api.BUILD", @@ -73,3 +78,10 @@ def proxy_wasm_cpp_host_repositories(): strip_prefix = "protobuf-655310ca192a6e3a050e0ca0b7084a2968072260", url = "https://github.com/protocolbuffers/protobuf/archive/655310ca192a6e3a050e0ca0b7084a2968072260.tar.gz", ) + + http_archive( + name = "rules_foreign_cc", + sha256 = "d54742ffbdc6924f222d2179f0e10e911c5c659c4ae74158e9fe827aad862ac6", + strip_prefix = "rules_foreign_cc-0.2.0", + url = "https://github.com/bazelbuild/rules_foreign_cc/archive/0.2.0.tar.gz", + ) diff --git a/src/wamr/types.h b/src/wamr/types.h index 34b8f41f..4ea9c4fb 100644 --- a/src/wamr/types.h +++ b/src/wamr/types.h @@ -13,7 +13,7 @@ // limitations under the License. #include "src/common/types.h" -#include "wamr/include/wasm_c_api.h" +#include "wasm_c_api.h" namespace proxy_wasm { namespace wamr { diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 13ea2786..2d95a28e 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -30,7 +30,7 @@ #include #include "src/wamr/types.h" -#include "wamr/include/wasm_c_api.h" +#include "wasm_c_api.h" namespace proxy_wasm { namespace wamr { @@ -60,7 +60,6 @@ class Wamr : public WasmVm { Cloneable cloneable() override { return Cloneable::CompiledBytecode; - ; } std::unique_ptr clone() override; @@ -167,7 +166,7 @@ std::unique_ptr Wamr::clone() { WasmByteVec stripped; clone->module_ = - wasm_module_new(store_.get(), getStrippedSource(&stripped) ? stripped.get() : source_.get()); + wasm_module_new(clone->store_.get(), getStrippedSource(&stripped) ? stripped.get() : source_.get()); return clone; } From 2ea172cafda2b21294a8e0707d2f002a7fb7eb13 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Thu, 18 Mar 2021 01:47:33 +0000 Subject: [PATCH 08/19] Implement the proxy-wasm interface wasm_vm WAMR is commom WASM c/c++ API based, implenment same as wasitime Co-authored-by: Liang He Signed-off-by: Le Yao --- src/wamr/wamr.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 2d95a28e..233ba7ec 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -58,9 +58,7 @@ class Wamr : public WasmVm { std::string_view runtime() override { return "wamr"; } std::string_view getPrecompiledSectionName() override { return ""; } - Cloneable cloneable() override { - return Cloneable::CompiledBytecode; - } + Cloneable cloneable() override { return Cloneable::CompiledBytecode; } std::unique_ptr clone() override; AbiVersion getAbiVersion() override; @@ -165,8 +163,9 @@ std::unique_ptr Wamr::clone() { clone->store_ = wasm_store_new(engine()); WasmByteVec stripped; - clone->module_ = - wasm_module_new(clone->store_.get(), getStrippedSource(&stripped) ? stripped.get() : source_.get()); + clone->module_ = wasm_module_new(clone->store_.get(), + getStrippedSource(&stripped) ? stripped.get() : source_.get()); + return clone; } @@ -302,6 +301,7 @@ bool Wamr::link(std::string_view debug_name) { assert(module_ != nullptr); WasmImporttypeVec import_types; +This conversation was marked as resolved by leyao-daily wasm_module_imports(module_.get(), import_types.get()); std::vector imports; From 2ad5f1840c0b549ee415266ccdcf8d499080e79e Mon Sep 17 00:00:00 2001 From: Le Yao Date: Fri, 19 Mar 2021 02:55:04 +0000 Subject: [PATCH 09/19] Bazel build the runtime from external WAMR repo Build and testing runtime Signed-off-by: Le Yao --- bazel/external/wamr.BUILD | 2 +- src/wamr/types.h | 2 +- src/wamr/wamr.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bazel/external/wamr.BUILD b/bazel/external/wamr.BUILD index 32d20060..bd17f6e1 100644 --- a/bazel/external/wamr.BUILD +++ b/bazel/external/wamr.BUILD @@ -21,4 +21,4 @@ cmake( lib_source = ":srcs", out_shared_libs = ["libiwasm.so"], working_directory = "product-mini/platforms/linux" -) \ No newline at end of file +) diff --git a/src/wamr/types.h b/src/wamr/types.h index 4ea9c4fb..34b8f41f 100644 --- a/src/wamr/types.h +++ b/src/wamr/types.h @@ -13,7 +13,7 @@ // limitations under the License. #include "src/common/types.h" -#include "wasm_c_api.h" +#include "wamr/include/wasm_c_api.h" namespace proxy_wasm { namespace wamr { diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 233ba7ec..4d5e14a5 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -30,7 +30,7 @@ #include #include "src/wamr/types.h" -#include "wasm_c_api.h" +#include "wamr/include/wasm_c_api.h" namespace proxy_wasm { namespace wamr { From 05502ed2302a312ba2993818a769ee7b79e9c550 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Tue, 6 Apr 2021 06:51:42 +0000 Subject: [PATCH 10/19] Fix sha256 check and format Signed-off-by: Le Yao --- bazel/repositories.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 8668d4a6..e4f1f2cf 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -47,7 +47,7 @@ def proxy_wasm_cpp_host_repositories(): http_archive( name = "wamr", build_file = "@proxy_wasm_cpp_host//bazel/external:wamr.BUILD", - sha256 = "88cd7145d7098daacfb0da51548327f4e5303d17ea27611cde6f47c6f7b68059", + sha256 = "f819b9ec866a12086233e578044dd8297e6be86f0f17807b16124f78a3652d4f", url = "https://github.com/lum1n0us/wasm-micro-runtime/releases/download/WAMR-01-29-2021/source.zip", ) From fa6fd6f51196e0fc3d1c180c57e13115b9c9c7db Mon Sep 17 00:00:00 2001 From: Le Yao Date: Wed, 14 Apr 2021 06:44:56 +0000 Subject: [PATCH 11/19] Update to the latest branch and drop the merge pull Co-authored-by: Liang He Signed-off-by: Le Yao --- src/wamr/wamr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 4d5e14a5..233ba7ec 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -30,7 +30,7 @@ #include #include "src/wamr/types.h" -#include "wamr/include/wasm_c_api.h" +#include "wasm_c_api.h" namespace proxy_wasm { namespace wamr { From 7eadc8d915d29955635099fe6554c95e7d736528 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Wed, 14 Apr 2021 07:43:34 +0000 Subject: [PATCH 12/19] Update WAMR implementation based on Common utils INFO: Analyzed 9 targets (0 packages loaded, 0 targets configured). INFO: Found 1 target and 8 test targets... INFO: Elapsed time: 4.954s, Critical Path: 3.83s INFO: 25 processes: 2 internal, 23 linux-sandbox. INFO: Build completed successfully, 25 total actions //test:context_test PASSED in 0.1s //test:exports_test PASSED in 0.1s //test:null_vm_test PASSED in 0.2s //test:runtime_test PASSED in 0.1s //test:shared_data PASSED in 0.1s //test:shared_queue PASSED in 0.1s //test:vm_id_handle PASSED in 0.1s //test/common:bytecode_util_test PASSED in 0.2s Executed 8 out of 8 tests: 8 tests pass. INFO: Build completed successfully, 25 total actions Signed-off-by: Le Yao --- src/wamr/types.h | 2 +- src/wamr/wamr.cc | 160 +++++++---------------------------------------- 2 files changed, 25 insertions(+), 137 deletions(-) diff --git a/src/wamr/types.h b/src/wamr/types.h index 34b8f41f..4ea9c4fb 100644 --- a/src/wamr/types.h +++ b/src/wamr/types.h @@ -13,7 +13,7 @@ // limitations under the License. #include "src/common/types.h" -#include "wamr/include/wasm_c_api.h" +#include "wasm_c_api.h" namespace proxy_wasm { namespace wamr { diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 233ba7ec..f4316ba7 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -31,6 +31,7 @@ #include "src/wamr/types.h" #include "wasm_c_api.h" +#include "src/common/bytecode_util.h" namespace proxy_wasm { namespace wamr { @@ -62,7 +63,6 @@ class Wamr : public WasmVm { std::unique_ptr clone() override; AbiVersion getAbiVersion() override; - std::string_view getCustomSection(std::string_view name) override; bool load(const std::string &code, bool allow_precompiled = false) override; bool link(std::string_view debug_name) override; @@ -88,8 +88,6 @@ class Wamr : public WasmVm { FOR_ALL_WASM_VM_EXPORTS(_GET_MODULE_FUNCTION) #undef _GET_MODULE_FUNCTION private: - bool getStrippedSource(WasmByteVec *out); - template void registerHostFunctionImpl(std::string_view module_name, std::string_view function_name, void (*function)(void *, Args...)); @@ -106,7 +104,6 @@ class Wamr : public WasmVm { void getModuleFunctionImpl(std::string_view function_name, std::function *function); - WasmByteVec source_; WasmStorePtr store_; WasmModulePtr module_; WasmInstancePtr instance_; @@ -116,39 +113,27 @@ class Wamr : public WasmVm { std::unordered_map host_functions_; std::unordered_map module_functions_; + AbiVersion abi_version_; }; -// TODO(mathetake): move to proxy_wasm::common::* -static uint32_t parseVarint(const byte_t *&pos, const byte_t *end) { - uint32_t n = 0; - uint32_t shift = 0; - byte_t b; - do { - if (pos + 1 > end) { - abort(); - } - b = *pos++; - n += (b & 0x7f) << shift; - shift += 7; - } while ((b & 0x80) != 0); - return n; -} - bool Wamr::load(const std::string &code, bool allow_precompiled) { store_ = wasm_store_new(engine()); - // Wasm file header is 8 bytes (magic number + version). - static const uint8_t magic_number[4] = {0x00, 0x61, 0x73, 0x6d}; - if (code.size() < 8 || ::memcmp(code.data(), magic_number, 4) != 0) { + // Get ABI version from bytecode. + if (!common::BytecodeUtil::getAbiVersion(code, abi_version_)) { + fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); return false; } - wasm_byte_vec_new_uninitialized(source_.get(), code.size()); - ::memcpy(source_.get()->data, code.data(), code.size()); + std::string stripped; + if (!common::BytecodeUtil::getStrippedSource(code, stripped)) { + fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); + return false; + }; - WasmByteVec stripped; - module_ = - wasm_module_new(store_.get(), getStrippedSource(&stripped) ? stripped.get() : source_.get()); + WasmByteVec stripped_vec; + wasm_byte_vec_new(stripped_vec.get(), stripped.size(), stripped.data()); + module_ = wasm_module_new(store_.get(), stripped_vec.get()); return module_ != nullptr; } @@ -162,60 +147,19 @@ std::unique_ptr Wamr::clone() { clone->store_ = wasm_store_new(engine()); - WasmByteVec stripped; - clone->module_ = wasm_module_new(clone->store_.get(), - getStrippedSource(&stripped) ? stripped.get() : source_.get()); - - return clone; -} + std::string stripped; + if (!common::BytecodeUtil::getStrippedSource("", stripped)) { + fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); + return nullptr; + }; -// TODO(mathetake): move to proxy_wasm::common::* -bool Wamr::getStrippedSource(WasmByteVec *out) { - std::vector stripped; + WasmByteVec stripped_vec; + wasm_byte_vec_new(stripped_vec.get(), stripped.size(), stripped.data()); + clone->module_ = wasm_module_new(store_.get(), stripped_vec.get()); - const byte_t *pos = source_.get()->data + 8 /* Wasm header */; - const byte_t *end = source_.get()->data + source_.get()->size; - while (pos < end) { - const auto section_start = pos; - if (pos + 1 > end) { - return false; - } - const auto section_type = *pos++; - const auto section_len = parseVarint(pos, end); - if (section_len == static_cast(-1) || pos + section_len > end) { - return false; - } - if (section_type == 0 /* custom section */) { - const auto section_data_start = pos; - const auto section_name_len = parseVarint(pos, end); - if (section_name_len == static_cast(-1) || pos + section_name_len > end) { - return false; - } - auto section_name = std::string_view(pos, section_name_len); - if (section_name.find("precompiled_") != std::string::npos) { - // If this is the first "precompiled_" section, then save everything - // before it, otherwise skip it. - if (stripped.empty()) { - const byte_t *start = source_.get()->data; - stripped.insert(stripped.end(), start, section_start); - } - } - pos = section_data_start + section_len; - } else { - pos += section_len; - // Save this section if we already saw a custom "precompiled_" section. - if (!stripped.empty()) { - stripped.insert(stripped.end(), section_start, pos /* section end */); - } - } - } + clone->abi_version_ = abi_version_; - if (!stripped.empty()) { - wasm_byte_vec_new_uninitialized(out->get(), stripped.size()); - ::memcpy(out->get()->data, stripped.data(), stripped.size()); - return true; - } - return false; + return clone; } static bool equalValTypes(const wasm_valtype_vec_t *left, const wasm_valtype_vec_t *right) { @@ -301,7 +245,6 @@ bool Wamr::link(std::string_view debug_name) { assert(module_ != nullptr); WasmImporttypeVec import_types; -This conversation was marked as resolved by leyao-daily wasm_module_imports(module_.get(), import_types.get()); std::vector imports; @@ -406,41 +349,6 @@ This conversation was marked as resolved by leyao-daily return true; } -std::string_view Wamr::getCustomSection(std::string_view name) { - const byte_t *pos = source_.get()->data + 8 /* Wasm header */; - const byte_t *end = source_.get()->data + source_.get()->size; - while (pos < end) { - if (pos + 1 > end) { - fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); - return ""; - } - const auto section_type = *pos++; - const auto section_len = parseVarint(pos, end); - if (section_len == static_cast(-1) || pos + section_len > end) { - fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); - return ""; - } - - if (section_type == 0 /* custom section */) { - const auto section_data_start = pos; - const auto section_name_len = parseVarint(pos, end); - if (section_name_len == static_cast(-1) || pos + section_name_len > end) { - fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); - return ""; - } - if (section_name_len == name.size() && ::memcmp(pos, name.data(), section_name_len) == 0) { - pos += section_name_len; - return {pos, static_cast(section_data_start + section_len - pos)}; - } - pos = section_data_start + section_len; - } else { - pos += section_len; - } - } - - return ""; -} - uint64_t Wamr::getMemorySize() { return wasm_memory_data_size(memory_.get()); } std::optional Wamr::getMemory(uint64_t pointer, uint64_t size) { @@ -737,27 +645,7 @@ void Wamr::getModuleFunctionImpl(std::string_view function_name, }; }; -AbiVersion Wamr::getAbiVersion() { - assert(module_ != nullptr); - WasmExportTypeVec export_types; - wasm_module_exports(module_.get(), export_types.get()); - - for (size_t i = 0; i < export_types.get()->size; i++) { - const wasm_externtype_t *exp_extern_type = wasm_exporttype_type(export_types.get()->data[i]); - if (wasm_externtype_kind(exp_extern_type) == WASM_EXTERN_FUNC) { - const wasm_name_t *name_ptr = wasm_exporttype_name(export_types.get()->data[i]); - std::string_view name(name_ptr->data, name_ptr->size); - if (name == "proxy_abi_version_0_1_0") { - return AbiVersion::ProxyWasm_0_1_0; - } else if (name == "proxy_abi_version_0_2_0") { - return AbiVersion::ProxyWasm_0_2_0; - } else if (name == "proxy_abi_version_0_2_1") { - return AbiVersion::ProxyWasm_0_2_1; - } - } - } - return AbiVersion::Unknown; -} +AbiVersion Wamr::getAbiVersion() { return abi_version_; } } // namespace wamr From e707a1fe0e71a6657ce9155317ce2f4670ab262f Mon Sep 17 00:00:00 2001 From: Le Yao Date: Wed, 14 Apr 2021 08:09:03 +0000 Subject: [PATCH 13/19] Set runtime not cloneable INFO: Analyzed 9 targets (0 packages loaded, 0 targets configured). INFO: Found 1 target and 8 test targets... INFO: Elapsed time: 4.541s, Critical Path: 3.48s INFO: 20 processes: 2 internal, 18 linux-sandbox. INFO: Build completed successfully, 20 total actions //test:context_test PASSED in 0.1s //test:exports_test PASSED in 0.1s //test:null_vm_test PASSED in 0.1s //test:runtime_test PASSED in 0.1s //test:shared_data PASSED in 0.1s //test:shared_queue PASSED in 0.1s //test:vm_id_handle PASSED in 0.1s //test/common:bytecode_util_test PASSED in 0.1s Executed 8 out of 8 tests: 8 tests pass. INFO: Build completed successfully, 20 total actions Signed-off-by: Le Yao --- src/wamr/wamr.cc | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index f4316ba7..310f4242 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -59,8 +59,8 @@ class Wamr : public WasmVm { std::string_view runtime() override { return "wamr"; } std::string_view getPrecompiledSectionName() override { return ""; } - Cloneable cloneable() override { return Cloneable::CompiledBytecode; } - std::unique_ptr clone() override; + Cloneable cloneable() override { return Cloneable::NotCloneable; } + std::unique_ptr clone() override { return nullptr; }; AbiVersion getAbiVersion() override; @@ -138,30 +138,6 @@ bool Wamr::load(const std::string &code, bool allow_precompiled) { return module_ != nullptr; } -std::unique_ptr Wamr::clone() { - assert(module_ != nullptr); - - auto clone = std::make_unique(); - - clone->integration().reset(integration()->clone()); - - clone->store_ = wasm_store_new(engine()); - - std::string stripped; - if (!common::BytecodeUtil::getStrippedSource("", stripped)) { - fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module"); - return nullptr; - }; - - WasmByteVec stripped_vec; - wasm_byte_vec_new(stripped_vec.get(), stripped.size(), stripped.data()); - clone->module_ = wasm_module_new(store_.get(), stripped_vec.get()); - - clone->abi_version_ = abi_version_; - - return clone; -} - static bool equalValTypes(const wasm_valtype_vec_t *left, const wasm_valtype_vec_t *right) { if (left->size != right->size) { return false; From f8bf470803284359d55bd5c408682859285c66a1 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Thu, 15 Apr 2021 01:09:31 +0000 Subject: [PATCH 14/19] Revert the BUILD and remove local configuration Starting local Bazel server and connecting to it... DEBUG: Rule 'proxy_wasm_cpp_host__wasmtime_c_api_macros__0_19_0' indicated that a canonical reproducible form can be obtained by modifying arguments shallow_since = "1617649269 -0700" DEBUG: Repository proxy_wasm_cpp_host__wasmtime_c_api_macros__0_19_0 instantiated at: /root/proxy-wasm-cpp-host/WORKSPACE:9:33: in /root/.cache/bazel/_bazel_root/5d3cda4fc30ff6fff6d96ed8522a1d40/external/proxy_wasm_cpp_host/bazel/dependencies.bzl:20:44: in proxy_wasm_cpp_host_dependencies /root/.cache/bazel/_bazel_root/5d3cda4fc30ff6fff6d96ed8522a1d40/external/proxy_wasm_cpp_host/bazel/cargo/crates.bzl:724:10: in proxy_wasm_cpp_host_fetch_remote_crates /root/.cache/bazel/_bazel_root/5d3cda4fc30ff6fff6d96ed8522a1d40/external/bazel_tools/tools/build_defs/repo/utils.bzl:201:18: in maybe Repository rule new_git_repository defined at: /root/.cache/bazel/_bazel_root/5d3cda4fc30ff6fff6d96ed8522a1d40/external/bazel_tools/tools/build_defs/repo/git.bzl:186:37: in INFO: Analyzed 9 targets (131 packages loaded, 34267 targets configured). INFO: Found 1 target and 8 test targets... INFO: Elapsed time: 117.312s, Critical Path: 101.49s INFO: 334 processes: 165 internal, 169 linux-sandbox. INFO: Build completed successfully, 334 total actions //test:context_test PASSED in 0.1s //test:exports_test PASSED in 5.7s //test:null_vm_test PASSED in 0.1s //test:runtime_test PASSED in 2.0s //test:shared_data PASSED in 0.1s //test:shared_queue PASSED in 0.1s //test:vm_id_handle PASSED in 0.1s //test/common:bytecode_util_test PASSED in 0.1s Executed 8 out of 8 tests: 8 tests pass. INFO: Build completed successfully, 334 total actions Signed-off-by: Le Yao --- BUILD | 4 ++-- WORKSPACE | 2 +- bazel/external/wamr.BUILD | 1 - bazel/repositories.bzl | 20 +++++++------------- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/BUILD b/BUILD index e160ae48..74e861df 100644 --- a/BUILD +++ b/BUILD @@ -24,7 +24,7 @@ cc_library( ], exclude = [ "src/**/v8*", - "src/**/wasmtime*", + "src/**/wamr*", "src/**/wavm*", ], ), @@ -35,6 +35,6 @@ cc_library( "@boringssl//:crypto", "@com_google_protobuf//:protobuf_lite", "@proxy_wasm_cpp_sdk//:api_lib", - "@wamr//:libiwasm", + "@wasm_c_api//:wasmtime_lib", ], ) diff --git a/WORKSPACE b/WORKSPACE index 48a10fb5..2008efc3 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -10,4 +10,4 @@ proxy_wasm_cpp_host_dependencies() load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies") -rules_foreign_cc_dependencies() \ No newline at end of file +rules_foreign_cc_dependencies() diff --git a/bazel/external/wamr.BUILD b/bazel/external/wamr.BUILD index bd17f6e1..0f8aaca1 100644 --- a/bazel/external/wamr.BUILD +++ b/bazel/external/wamr.BUILD @@ -13,7 +13,6 @@ filegroup( cmake( name = "libiwasm", cache_entries = { - "CMAKE_BUILD_TYPE": "Debug", "CMAKE_EXPORT_COMPILE_COMMANDS": "On", "WAMR_BUILD_AOT": "0", "WAMR_BUILD_SIMD": "0", diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index e4f1f2cf..2dd19410 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -36,14 +36,6 @@ def proxy_wasm_cpp_host_repositories(): urls = ["https://github.com/google/googletest/archive/release-1.10.0.tar.gz"], ) - http_archive( - name = "wasmtime", - build_file = "@proxy_wasm_cpp_host//bazel/external:wasmtime.BUILD", - sha256 = "e95d274822ac72bf06355bdfbeddcacae60d7e98fec8ee4b2e21740636fb5c2c", - strip_prefix = "wasmtime-0.26.0", - url = "https://github.com/bytecodealliance/wasmtime/archive/v0.26.0.tar.gz", - ) - http_archive( name = "wamr", build_file = "@proxy_wasm_cpp_host//bazel/external:wamr.BUILD", @@ -51,11 +43,13 @@ def proxy_wasm_cpp_host_repositories(): url = "https://github.com/lum1n0us/wasm-micro-runtime/releases/download/WAMR-01-29-2021/source.zip", ) - # native.new_local_repository( - # name = "wamr", - # build_file = "@proxy_wasm_cpp_host//bazel/external:wamr.BUILD", - # path = "/source/wamr", - # ) + http_archive( + name = "wasmtime", + build_file = "@proxy_wasm_cpp_host//bazel/external:wasmtime.BUILD", + sha256 = "e95d274822ac72bf06355bdfbeddcacae60d7e98fec8ee4b2e21740636fb5c2c", + strip_prefix = "wasmtime-0.26.0", + url = "https://github.com/bytecodealliance/wasmtime/archive/v0.26.0.tar.gz", + ) http_archive( name = "wasm_c_api", From aac13942e946c2e789e9d2f4987621ab92c6bfbf Mon Sep 17 00:00:00 2001 From: Le Yao Date: Thu, 15 Apr 2021 01:43:48 +0000 Subject: [PATCH 15/19] Avoid unnecessary log level checks INFO: Analyzed 9 targets (5 packages loaded, 930 targets configured). INFO: Found 1 target and 8 test targets... INFO: Elapsed time: 5.281s, Critical Path: 0.02s INFO: 1 process: 1 internal. INFO: Build completed successfully, 1 total action //test:context_test (cached) PASSED in 0.1s //test:exports_test (cached) PASSED in 5.7s //test:null_vm_test (cached) PASSED in 0.1s //test:runtime_test (cached) PASSED in 2.0s //test:shared_data (cached) PASSED in 0.1s //test:shared_queue (cached) PASSED in 0.1s //test:vm_id_handle (cached) PASSED in 0.1s //test/common:bytecode_util_test (cached) PASSED in 0.1s Executed 0 out of 8 tests: 8 tests pass. INFO: Build completed successfully, 1 total action Signed-off-by: Le Yao --- src/wamr/wamr.cc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 310f4242..0f9640db 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -468,7 +468,8 @@ void Wamr::registerHostFunctionImpl(std::string_view module_name, std::string_vi store_.get(), type.get(), [](void *data, const wasm_val_t params[], wasm_val_t results[]) -> wasm_trap_t * { auto func_data = reinterpret_cast(data); - if (func_data->vm_->cmpLogLevel(LogLevel::trace)) { + const bool log = func_data->vm_->cmpLogLevel(LogLevel::trace); + if (log) { func_data->vm_->integration()->trace("[vm->host] " + func_data->name_ + "(" + printValues(params, sizeof...(Args)) + ")"); } @@ -476,7 +477,7 @@ void Wamr::registerHostFunctionImpl(std::string_view module_name, std::string_vi auto args = std::tuple_cat(std::make_tuple(current_context_), args_tuple); auto fn = reinterpret_cast(func_data->raw_func_); std::apply(fn, args); - if (func_data->vm_->cmpLogLevel(LogLevel::trace)) { + if (log) { func_data->vm_->integration()->trace("[vm<-host] " + func_data->name_ + " return: void"); } return nullptr; @@ -500,7 +501,8 @@ void Wamr::registerHostFunctionImpl(std::string_view module_name, std::string_vi store_.get(), type.get(), [](void *data, const wasm_val_t params[], wasm_val_t results[]) -> wasm_trap_t * { auto func_data = reinterpret_cast(data); - if (func_data->vm_->cmpLogLevel(LogLevel::trace)) { + const bool log = func_data->vm_->cmpLogLevel(LogLevel::trace); + if (log) { func_data->vm_->integration()->trace("[vm->host] " + func_data->name_ + "(" + printValues(params, sizeof...(Args)) + ")"); } @@ -509,7 +511,7 @@ void Wamr::registerHostFunctionImpl(std::string_view module_name, std::string_vi auto fn = reinterpret_cast(func_data->raw_func_); R res = std::apply(fn, args); assignVal(res, results[0]); - if (func_data->vm_->cmpLogLevel(LogLevel::trace)) { + if (log) { func_data->vm_->integration()->trace("[vm<-host] " + func_data->name_ + " return: " + std::to_string(res)); } @@ -552,11 +554,12 @@ void Wamr::getModuleFunctionImpl(std::string_view function_name, *function = [func, function_name, this](ContextBase *context, Args... args) -> void { wasm_val_t params[] = {makeVal(args)...}; - SaveRestoreContext saved_context(context); - if (cmpLogLevel(LogLevel::trace)) { + const bool log = cmpLogLevel(LogLevel::trace); + if (log) { integration()->trace("[host->vm] " + std::string(function_name) + "(" + printValues(params, sizeof...(Args)) + ")"); } + SaveRestoreContext saved_context(context); WasmTrapPtr trap{wasm_func_call(func, params, nullptr)}; if (trap) { WasmByteVec error_message; @@ -566,7 +569,7 @@ void Wamr::getModuleFunctionImpl(std::string_view function_name, std::string(error_message.get()->data, error_message.get()->size)); return; } - if (cmpLogLevel(LogLevel::trace)) { + if (log) { integration()->trace("[host<-vm] " + std::string(function_name) + " return: void"); } }; @@ -598,11 +601,12 @@ void Wamr::getModuleFunctionImpl(std::string_view function_name, *function = [func, function_name, this](ContextBase *context, Args... args) -> R { wasm_val_t params[] = {makeVal(args)...}; wasm_val_t results[1]; - SaveRestoreContext saved_context(context); - if (cmpLogLevel(LogLevel::trace)) { + const bool log = cmpLogLevel(LogLevel::trace); + if (log) { integration()->trace("[host->vm] " + std::string(function_name) + "(" + printValues(params, sizeof...(Args)) + ")"); } + SaveRestoreContext saved_context(context); WasmTrapPtr trap{wasm_func_call(func, params, results)}; if (trap) { WasmByteVec error_message; @@ -613,7 +617,7 @@ void Wamr::getModuleFunctionImpl(std::string_view function_name, return R{}; } R ret = convertValueTypeToArg(results[0]); - if (cmpLogLevel(LogLevel::trace)) { + if (log) { integration()->trace("[host<-vm] " + std::string(function_name) + " return: " + std::to_string(ret)); } From b1cd9bcebf425b80c2284d739a536a3e18b8d90a Mon Sep 17 00:00:00 2001 From: liam Date: Fri, 19 Mar 2021 02:55:04 +0000 Subject: [PATCH 16/19] dont use smart pointers to transfer vector data since `wasm_functype_new` will transfer data ownerships of both `params` and `resutls` to the new `wasm_functype_t`, we should not - delete `wasm_valtype_t` of `wasm_valtype_vec_t` - use `wasm_functype_delete` to release members of `wasm_functype_t` a good example will be found here: [multi.c](https://github.com/WebAssembly/wasm-c-api/blob/master/example/multi.c) another thing is the runtime() should return a string as same as the one in envoy.yaml update wamr code release to 0.1-beta Signed-off-by: liam --- bazel/external/wamr.BUILD | 4 ++-- bazel/repositories.bzl | 5 +++-- src/wamr/wamr.cc | 23 ++++++++++------------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/bazel/external/wamr.BUILD b/bazel/external/wamr.BUILD index 0f8aaca1..cca10313 100644 --- a/bazel/external/wamr.BUILD +++ b/bazel/external/wamr.BUILD @@ -13,11 +13,11 @@ filegroup( cmake( name = "libiwasm", cache_entries = { - "CMAKE_EXPORT_COMPILE_COMMANDS": "On", "WAMR_BUILD_AOT": "0", "WAMR_BUILD_SIMD": "0", + "WAMR_BUILD_MULTI_MODULE": "1", + "WAMR_BUILD_LIBC_WASI": "0", }, lib_source = ":srcs", out_shared_libs = ["libiwasm.so"], - working_directory = "product-mini/platforms/linux" ) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 2dd19410..5c34a499 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -39,8 +39,9 @@ def proxy_wasm_cpp_host_repositories(): http_archive( name = "wamr", build_file = "@proxy_wasm_cpp_host//bazel/external:wamr.BUILD", - sha256 = "f819b9ec866a12086233e578044dd8297e6be86f0f17807b16124f78a3652d4f", - url = "https://github.com/lum1n0us/wasm-micro-runtime/releases/download/WAMR-01-29-2021/source.zip", + sha256 = "3f9c993cf81a573cd733b7d97fa15ed757351881e502aad22ff873371ee55202", + strip_prefix = "wasm-micro-runtime-0.1-beta", + url = "https://github.com/lum1n0us/wasm-micro-runtime/archive/refs/tags/v0.1-beta.tar.gz", ) http_archive( diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 0f9640db..6dfde20c 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -56,11 +56,11 @@ class Wamr : public WasmVm { public: Wamr() {} - std::string_view runtime() override { return "wamr"; } + std::string_view runtime() override { return "envoy.wasm.runtime.wamr"; } std::string_view getPrecompiledSectionName() override { return ""; } Cloneable cloneable() override { return Cloneable::NotCloneable; } - std::unique_ptr clone() override { return nullptr; }; + std::unique_ptr clone() override { return nullptr; } AbiVersion getAbiVersion() override; @@ -433,9 +433,6 @@ void convertArgsTupleToValTypesImpl(wasm_valtype_vec_t *types, std::index_sequen auto ps = std::array::value>{ convertArgToValTypePtr::type>()...}; wasm_valtype_vec_new(types, size, ps.data()); - for (auto i = ps.begin(); i < ps.end(); i++) { // TODO(mathetake): better way to handle? - wasm_valtype_delete(*i); - } } template ::value>> @@ -444,17 +441,17 @@ void convertArgsTupleToValTypes(wasm_valtype_vec_t *types) { } template WasmFunctypePtr newWasmNewFuncType() { - WasmValtypeVec params, results; - convertArgsTupleToValTypes(params.get()); - convertArgsTupleToValTypes>(results.get()); - return wasm_functype_new(params.get(), results.get()); + wasm_valtype_vec_t params, results; + convertArgsTupleToValTypes(¶ms); + convertArgsTupleToValTypes>(&results); + return wasm_functype_new(¶ms, &results); } template WasmFunctypePtr newWasmNewFuncType() { - WasmValtypeVec params, results; - convertArgsTupleToValTypes(params.get()); - convertArgsTupleToValTypes>(results.get()); - return wasm_functype_new(params.get(), results.get()); + wasm_valtype_vec_t params, results; + convertArgsTupleToValTypes(¶ms); + convertArgsTupleToValTypes>(&results); + return wasm_functype_new(¶ms, &results); } template From 86ee01b9bf6e78078bf3c21592eea14798fedd62 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Sun, 25 Apr 2021 03:11:06 +0000 Subject: [PATCH 17/19] Update to the latest repo Signed-off-by: Le Yao --- bazel/repositories.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 5c34a499..b490139b 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -39,9 +39,9 @@ def proxy_wasm_cpp_host_repositories(): http_archive( name = "wamr", build_file = "@proxy_wasm_cpp_host//bazel/external:wamr.BUILD", - sha256 = "3f9c993cf81a573cd733b7d97fa15ed757351881e502aad22ff873371ee55202", - strip_prefix = "wasm-micro-runtime-0.1-beta", - url = "https://github.com/lum1n0us/wasm-micro-runtime/archive/refs/tags/v0.1-beta.tar.gz", + sha256 = "1d219d4121badc23b0743af2e7dc7e04348ace309748541deba897709f2d90b6", + strip_prefix = "wasm-micro-runtime-67fa1602031f5b86d195a3b1d02d331fcb70f299", + url = "https://github.com/bytecodealliance/wasm-micro-runtime/archive/67fa1602031f5b86d195a3b1d02d331fcb70f299.tar.gz", ) http_archive( From f569d10cba74bdfc6f6dfba7a3db94296d313a92 Mon Sep 17 00:00:00 2001 From: Le Yao Date: Fri, 30 Apr 2021 02:05:25 +0000 Subject: [PATCH 18/19] Apply the latest WAMR repo as dependency To the latest official commit Signed-off-by: Le Yao --- bazel/repositories.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index b490139b..d87c8fbb 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -39,9 +39,9 @@ def proxy_wasm_cpp_host_repositories(): http_archive( name = "wamr", build_file = "@proxy_wasm_cpp_host//bazel/external:wamr.BUILD", - sha256 = "1d219d4121badc23b0743af2e7dc7e04348ace309748541deba897709f2d90b6", - strip_prefix = "wasm-micro-runtime-67fa1602031f5b86d195a3b1d02d331fcb70f299", - url = "https://github.com/bytecodealliance/wasm-micro-runtime/archive/67fa1602031f5b86d195a3b1d02d331fcb70f299.tar.gz", + sha256 = "1d870f396bb6bdcb5c816326655b19a2877bbdf879255c335b8e84ce4ee37780", + strip_prefix = "wasm-micro-runtime-9710d9325f426121cc1f2c62386a71d0c022d613", + url = "https://github.com/bytecodealliance/wasm-micro-runtime/archive/9710d9325f426121cc1f2c62386a71d0c022d613.tar.gz", ) http_archive( From 55cdd8efd1264c7d53de01836b84d422f2d1d2df Mon Sep 17 00:00:00 2001 From: Le Yao Date: Thu, 6 May 2021 02:21:31 +0000 Subject: [PATCH 19/19] Match the build params Signed-off-by: Le Yao --- bazel/external/wamr.BUILD | 2 ++ src/wamr/wamr.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bazel/external/wamr.BUILD b/bazel/external/wamr.BUILD index cca10313..f1d82a06 100644 --- a/bazel/external/wamr.BUILD +++ b/bazel/external/wamr.BUILD @@ -13,6 +13,8 @@ filegroup( cmake( name = "libiwasm", cache_entries = { + "WAMR_BUILD_INTERP": "1", + "WAMR_BUILD_JIT": "0", "WAMR_BUILD_AOT": "0", "WAMR_BUILD_SIMD": "0", "WAMR_BUILD_MULTI_MODULE": "1", diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 6dfde20c..5cc63f06 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -56,7 +56,7 @@ class Wamr : public WasmVm { public: Wamr() {} - std::string_view runtime() override { return "envoy.wasm.runtime.wamr"; } + std::string_view runtime() override { return "wamr"; } std::string_view getPrecompiledSectionName() override { return ""; } Cloneable cloneable() override { return Cloneable::NotCloneable; }