Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
cmake_minimum_required(VERSION 3.13.4)
project(WASM2BRS VERSION 1.0.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

add_subdirectory(third_party/wabt)
set(BUILD_TESTS OFF)
add_subdirectory(third_party/binaryen)

include_directories(${WABT_SOURCE_DIR} ${WABT_BINARY_DIR})
Expand Down
4 changes: 2 additions & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ ENV WASMER_DIR="/home/user/.wasmer"
ENV WASMER_CACHE_DIR="/home/user/.wasmer/cache"
ENV PATH="/home/user/.wasmer/bin:/home/user/.wasienv/bin/:${PATH}:/home/user/.wasmer/globals/wapm_packages/.bin"

RUN curl -sSf https://sh.rustup.rs | bash -s -- -y
RUN curl -sSf https://sh.rustup.rs | bash -s -- -y --default-toolchain=1.81.0
ENV PATH="/home/user/.cargo/bin:${PATH}"
RUN rustup target add wasm32-wasi
RUN cargo install cargo-wasi
RUN cargo install --locked cargo-wasi

ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD echo "No command specified"
6 changes: 3 additions & 3 deletions samples/rust/rust.brs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Function Start()
w2bInit__()
wasi_init(m.w2b_memory, "rust.wasm", {})
w2b__start()
_rust_wasmInit__()
wasi_init(m._rust_wasm_memory, "rust.wasm", {})
_rust_wasm__start()
wasi_shutdown()
End Function
105 changes: 60 additions & 45 deletions src/brs-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,22 @@

#include <cctype>
#include <cinttypes>
#include <iterator>
#include <limits>
#include <map>
#include <set>
#include <iostream>
#include <regex>
#include <string_view>
#include <vector>

#include "src/cast.h"
#include "src/common.h"
#include "src/ir.h"
#include "src/literal.h"
#include "src/stream.h"
#include "src/string-view.h"
#include "wabt/cast.h"
#include "wabt/common.h"
#include "wabt/ir.h"
#include "wabt/literal.h"
#include "wabt/sha256.h"
#include "wabt/stream.h"
#include "wabt/string-util.h"

#define INDENT_SIZE 2

Expand Down Expand Up @@ -156,7 +161,7 @@ class CWriter {

std::string GetFilename(size_t index);
FileStream OpenFileStream(size_t index);
void WriteModule(const Module&);
Result WriteModule(const Module&);

private:
typedef std::set<std::string> SymbolSet;
Expand All @@ -183,15 +188,15 @@ class CWriter {
static std::string Deref(const std::string&);

static char MangleType(Type);
static std::string LegalizeNameNoAddons(string_view);
std::string LegalizeName(const std::string& prefix, const std::string& module_name, string_view name);
std::string DefineName(SymbolSet*, string_view, const std::string& prefix = std::string());
static std::string LegalizeNameNoAddons(std::string_view);
std::string LegalizeName(const std::string& prefix, const std::string& module_name, std::string_view name);
std::string DefineName(SymbolSet*, std::string_view, const std::string& prefix = std::string());
std::string DefineImportName(const std::string& name,
string_view module_name,
string_view mangled_field_name);
std::string_view module_name,
std::string_view mangled_field_name);
std::string DefineGlobalScopeName(const std::string&, const std::string& prefix = std::string());
std::string DefineLocalScopeName(const std::string&);
std::string DefineStackVarName(Index, Type, string_view);
std::string DefineStackVarName(Index, Type, std::string_view);

void EndChunk();
void Indent(int size = INDENT_SIZE);
Expand All @@ -214,7 +219,7 @@ class CWriter {
void Write(OpenBrace);
void Write(CloseBrace);
void Write(Index);
void Write(string_view);
void Write(std::string_view);
void Write(const LocalName&);
void Write(const GlobalName&);
void Write(const ExternalPtr&);
Expand Down Expand Up @@ -286,6 +291,7 @@ class CWriter {
size_t label_count_ = 0;
MemoryStream stream_;
std::vector<std::string> chunks_;
Result result_ = Result::Ok;
int indent_ = 0;
bool should_write_indent_next_ = false;

Expand All @@ -301,14 +307,6 @@ class CWriter {

static const char kImplicitFuncLabel[] = "$Bfunc";

#define SECTION_NAME(x) s_header_##x
#include "src/prebuilt/wasm2c.include.h"
#undef SECTION_NAME

#define SECTION_NAME(x) s_source_##x
#include "src/prebuilt/wasm2c.include.c"
#undef SECTION_NAME

static bool IsReplaceableMemFunction(const wabt::Func& func) {
return
(func.name == "$memcpy" || func.name == "$memset") &&
Expand Down Expand Up @@ -415,7 +413,7 @@ char CWriter::MangleType(Type type) {
}
}

std::string CWriter::LegalizeNameNoAddons(string_view name) {
std::string CWriter::LegalizeNameNoAddons(std::string_view name) {
std::string result;
for (size_t i = 0; i < name.size(); ++i)
result += isalnum(name[i]) ? tolower(name[i]) : '_';
Expand All @@ -432,7 +430,7 @@ uint32_t adler32(const uint8_t* data, size_t len) {
return (b << 16) | a;
}

std::string CWriter::LegalizeName(const std::string& prefix, const std::string& module_name, string_view name) {
std::string CWriter::LegalizeName(const std::string& prefix, const std::string& module_name, std::string_view name) {
const std::string legalized = LegalizeNameNoAddons(name);
const std::string module_prefix = module_name == "env" ? "" : module_name + "_";
const std::string output = prefix + module_prefix + legalized;
Expand All @@ -441,7 +439,7 @@ std::string CWriter::LegalizeName(const std::string& prefix, const std::string&
: output + "_" + std::to_string(adler32((const uint8_t*)name.begin(), name.length()));
}

std::string CWriter::DefineName(SymbolSet* set, string_view name, const std::string& prefix) {
std::string CWriter::DefineName(SymbolSet* set, std::string_view name, const std::string& prefix) {
std::string legal = LegalizeName(prefix, options_.name_prefix, name);
if (set->find(legal) != set->end()) {
std::string base = legal + "_";
Expand All @@ -454,17 +452,17 @@ std::string CWriter::DefineName(SymbolSet* set, string_view name, const std::str
return legal;
}

string_view StripLeadingDollar(string_view name) {
std::string_view StripLeadingDollar(std::string_view name) {
if (!name.empty() && name[0] == '$') {
name.remove_prefix(1);
}
return name;
}

std::string CWriter::DefineImportName(const std::string& name,
string_view module,
string_view mangled_field_name) {
std::string mangled = mangled_field_name.to_string();
std::string_view module,
std::string_view mangled_field_name) {
std::string mangled(mangled_field_name);
import_syms_.insert(name);
global_syms_.insert(mangled);
global_sym_map_.insert(SymbolMap::value_type(name, mangled));
Expand All @@ -485,7 +483,7 @@ std::string CWriter::DefineLocalScopeName(const std::string& name) {

std::string CWriter::DefineStackVarName(Index index,
Type type,
string_view name) {
std::string_view name) {
std::string unique = DefineName(&local_syms_, name);
StackTypePair stp = {index, type};
stack_var_sym_map_.insert(StackVarSymbolMap::value_type(stp, unique));
Expand Down Expand Up @@ -554,7 +552,7 @@ void CWriter::Write(Index index) {
Writef("%" PRIindex, index);
}

void CWriter::Write(string_view s) {
void CWriter::Write(std::string_view s) {
WriteData(s.data(), s.size());
}

Expand Down Expand Up @@ -612,7 +610,7 @@ void CWriter::Write(const GotoLabel& goto_label) {
// We've generated names for all labels, so we should only be using an
// index when branching to the implicit function label, which can't be
// named.
Write("Goto ", Var(kImplicitFuncLabel));
Write("Goto ", Var(kImplicitFuncLabel, {}));
}
}

Expand Down Expand Up @@ -950,7 +948,9 @@ void CWriter::WriteDataInitializers() {
uint32_t max =
memory->page_limits.has_max ? memory->page_limits.max : 65536;
Write(ExternalPtr(memory->name), " = CreateObject(\"roByteArray\")", Newline());
Write(ExternalPtr(memory->name), "[", memory->page_limits.initial * WABT_PAGE_SIZE, "] = 0", Newline());
// TODO: should this be memory->page_size?
// 0x10000 = WABT_PAGE_SIZE
Write(ExternalPtr(memory->name), "[", memory->page_limits.initial * 0x10000, "] = 0", Newline());
Write(ExternalPtr(memory->name), "Max = ", max, Newline());
}

Expand Down Expand Up @@ -991,11 +991,13 @@ void CWriter::WriteElemInitializers() {
Write(Newline());

size_t i = 0;
for (const ElemExpr& elem_expr : elem_segment->elem_exprs) {
// We don't support the bulk-memory proposal here, so we know that we
// don't have any passive segments (where ref.null can be used).
assert(elem_expr.kind == ElemExprKind::RefFunc);
const Func* func = module_->GetFunc(elem_expr.var);
for (const ExprList& expr_list : elem_segment->elem_exprs) {
assert(expr_list.size() == 1);
const Expr& expr = expr_list.front();
assert(expr.type() == ExprType::RefFunc);

const RefFuncExpr& ref_func_expr = *cast<RefFuncExpr>(&expr);
const Func* func = module_->GetFunc(ref_func_expr.var);
Index func_type_index = module_->GetFuncTypeIndex(func->decl.type_var);

Write(ExternalRef(table->name), "[offset + ", i, "] = ", ExternalPtr(func->name), Newline());
Expand Down Expand Up @@ -1511,20 +1513,32 @@ void CWriter::Write(const ExprList& exprs) {
break;
}

case ExprType::MemoryCopy: {
const auto inst = cast<MemoryCopyExpr>(&expr);
Memory* dest_memory =
module_->memories[module_->GetMemoryIndex(inst->destmemidx)];
const Memory* src_memory = module_->GetMemory(inst->srcmemidx);
Write("MemoryCopy(",
ExternalRef(dest_memory->name), ", ",
StackVar(2), ", ",
ExternalRef(src_memory->name), ", ",
StackVar(1), ", ",
StackVar(0), ")", Newline());
DropTypes(3);
} break;

case ExprType::AtomicLoad:
case ExprType::AtomicRmw:
case ExprType::AtomicRmwCmpxchg:
case ExprType::AtomicStore:
case ExprType::AtomicWait:
case ExprType::AtomicFence:
case ExprType::AtomicNotify:
case ExprType::BrOnExn:
case ExprType::Rethrow:
case ExprType::ReturnCall:
case ExprType::ReturnCallIndirect:
case ExprType::Throw:
case ExprType::Try:
case ExprType::MemoryCopy:
case ExprType::DataDrop:
case ExprType::MemoryInit:
case ExprType::MemoryFill:
Expand Down Expand Up @@ -1565,7 +1579,7 @@ void CWriter::Write(const ExprList& exprs) {
case ExprType::Return:
// Goto the function label instead; this way we can do shared function
// cleanup code in one place.
Write(GotoLabel(Var(label_stack_.size() - 1)), Newline());
Write(GotoLabel(Var(label_stack_.size() - 1, {})), Newline());
// Stop processing this ExprList, since the following are unreachable.
return;

Expand Down Expand Up @@ -2429,7 +2443,7 @@ FileStream CWriter::OpenFileStream(size_t index) {
return FileStream(GetFilename(index).c_str());
}

void CWriter::WriteModule(const Module& module) {
Result CWriter::WriteModule(const Module& module) {
WABT_USE(options_);
module_ = &module;

Expand Down Expand Up @@ -2485,14 +2499,15 @@ void CWriter::WriteModule(const Module& module) {
lines += chunk_lines;
bytes += chunk_bytes;
}

return result_;
}

} // end anonymous namespace

Result WriteBrs(const Module* module, const WriteCOptions& options) {
CWriter c_writer(options);
c_writer.WriteModule(*module);
return Result::Ok;
CWriter brs_writer(options);
return brs_writer.WriteModule(*module);
}

} // namespace wabt
7 changes: 6 additions & 1 deletion src/brs-writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@
#ifndef WABT_C_WRITER_H_
#define WABT_C_WRITER_H_

#include "src/common.h"
#include <functional>
#include "wabt/common.h"
#include "wabt/feature.h"
#include "wabt/ir.h"

namespace wabt {

struct Module;
class Stream;

struct WriteCOptions {
std::string_view module_name;
Features features;
std::string name_prefix;
std::string out_filename;
};
Expand Down
Loading