Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Update binaryen APIs for platform-specific paths
  • Loading branch information
brson committed Feb 22, 2023
commit 570312ca700f53796db2bca3b5df4eb2071acb34
28 changes: 27 additions & 1 deletion src/support/command-line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,33 @@ Options& Options::add_positional(const std::string& name,
return *this;
}

void Options::parse(int argc, const char* argv[]) {
// This function converts the platform-specific pchar arrays to char arrays, on
// windows by converting from UTF-16 to UTF-8, then calls parse2.
//
// Further processing is the performed on plain chars and strings.
//
// For arguments that represent paths, the reverse UTF-8 to UTF-16 encoding will
// be performed (on windows) by the fspath constructor.
//
// On non-windows this is just copying bytes around without conversion.
void Options::parse(int argc, const pchar* argv[]) {
std::vector<std::vector<char>> utf8_argv;
std::vector<const char*> utf8_argv_ptrs;

for (int i = 0; i != argc; ++i) {
pstring arg = pstring(argv[i]);
std::string utf8_arg = pstring_to_string(arg);
std::vector<char> utf8_arg_vec(utf8_arg.begin(), utf8_arg.end());
utf8_arg_vec.push_back('\0');
auto ptr = utf8_arg_vec.data();
utf8_argv.push_back(std::move(utf8_arg_vec));
utf8_argv_ptrs.push_back(ptr);
}

Options::parse2(argc, utf8_argv_ptrs.data());
}

void Options::parse2(int argc, const char* argv[]) {
assert(argc > 0 && "expect at least program name as an argument");
size_t positionalsSeen = 0;
auto dashes = [](const std::string& s) {
Expand Down
5 changes: 4 additions & 1 deletion src/support/command-line.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <utility>
#include <vector>

#include "pchar.h"
#include "wasm.h"

namespace wasm {
Expand Down Expand Up @@ -63,9 +64,11 @@ class Options {
Options& add_positional(const std::string& name,
Arguments arguments,
const Action& action);
void parse(int argc, const char* argv[]);
void parse(int argc, const pchar* argv[]);

private:
void parse2(int argc, const char* argv[]);

struct Option {
std::string longName;
std::string shortName;
Expand Down
47 changes: 25 additions & 22 deletions src/support/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,26 @@ template<> std::string do_read_stdin<std::string>::operator()() {
}

template<typename T>
T wasm::read_file(const std::string& filename, Flags::BinaryOption binary) {
if (filename == "-") {
T wasm::read_file(const wasm::fspath& filename, Flags::BinaryOption binary) {
if (filename.stdpath() == "-") {
return do_read_stdin<T>{}();
}
BYN_TRACE("Loading '" << filename << "'...\n");
BYN_TRACE("Loading '" << filename.stdpath() << "'...\n");
std::ifstream infile;
std::ios_base::openmode flags = std::ifstream::in;
if (binary == Flags::Binary) {
flags |= std::ifstream::binary;
}
infile.open(filename, flags);
infile.open(filename.stdpath(), flags);
if (!infile.is_open()) {
Fatal() << "Failed opening '" << filename << "'";
Fatal() << "Failed opening '" << filename.stdpath() << "'";
}
infile.seekg(0, std::ios::end);
std::streampos insize = infile.tellg();
if (uint64_t(insize) >= std::numeric_limits<size_t>::max()) {
// Building a 32-bit executable where size_t == 32 bits, we are not able to
// create strings larger than 2^32 bytes in length, so must abort here.
Fatal() << "Failed opening '" << filename
Fatal() << "Failed opening '" << filename.stdpath()
<< "': Input file too large: " << insize
<< " bytes. Try rebuilding in 64-bit mode.";
}
Expand All @@ -87,47 +87,50 @@ T wasm::read_file(const std::string& filename, Flags::BinaryOption binary) {
return input;
}

std::string wasm::read_possible_response_file(const std::string& input) {
if (input.size() == 0 || input[0] != '@') {
return input;
std::string wasm::read_possible_response_file(const wasm::fspath& input) {
auto input_str = input.stdpath().native();
if (input_str.size() == 0 || input_str[0] != '@') {
return wasm::pstring_to_string(input.stdpath().native());
}
return wasm::read_file<std::string>(input.substr(1), Flags::Text);
auto input_substr = input_str.substr(1);
auto real_path = wasm::fspath::from_pstring(input_substr);
return wasm::read_file<std::string>(real_path, Flags::Text);
}

// Explicit instantiations for the explicit specializations.
template std::string wasm::read_file<>(const std::string&, Flags::BinaryOption);
template std::vector<char> wasm::read_file<>(const std::string&,
template std::string wasm::read_file<>(const wasm::fspath&, Flags::BinaryOption);
template std::vector<char> wasm::read_file<>(const wasm::fspath&,
Flags::BinaryOption);

wasm::Output::Output(const std::string& filename, Flags::BinaryOption binary)
wasm::Output::Output(const wasm::fspath& filename, Flags::BinaryOption binary)
: outfile(), out([this, filename, binary]() {
// Ensure a single return at the very end, to avoid clang-tidy warnings
// about the types of different returns here.
std::streambuf* buffer;
if (filename == "-" || filename.empty()) {
if (filename.stdpath() == "-" || filename.stdpath().empty()) {
buffer = std::cout.rdbuf();
} else {
BYN_TRACE("Opening '" << filename << "'\n");
BYN_TRACE("Opening '" << filename.stdpath() << "'\n");
auto flags = std::ofstream::out | std::ofstream::trunc;
if (binary == Flags::Binary) {
flags |= std::ofstream::binary;
}
outfile.open(filename, flags);
outfile.open(filename.stdpath(), flags);
if (!outfile.is_open()) {
Fatal() << "Failed opening '" << filename << "'";
Fatal() << "Failed opening '" << filename.stdpath() << "'";
}
buffer = outfile.rdbuf();
}
return buffer;
}()) {}

void wasm::copy_file(std::string input, std::string output) {
std::ifstream src(input, std::ios::binary);
std::ofstream dst(output, std::ios::binary);
void wasm::copy_file(wasm::fspath input, wasm::fspath output) {
std::ifstream src(input.stdpath(), std::ios::binary);
std::ofstream dst(output.stdpath(), std::ios::binary);
dst << src.rdbuf();
}

size_t wasm::file_size(std::string filename) {
std::ifstream infile(filename, std::ifstream::ate | std::ifstream::binary);
size_t wasm::file_size(wasm::fspath filename) {
std::ifstream infile(filename.stdpath(), std::ifstream::ate | std::ifstream::binary);
return infile.tellg();
}
16 changes: 9 additions & 7 deletions src/support/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <utility>
#include <vector>

#include "pchar.h"

namespace wasm {

namespace Flags {
Expand All @@ -35,23 +37,23 @@ enum BinaryOption { Binary, Text };
std::vector<char> read_stdin();

template<typename T>
T read_file(const std::string& filename, Flags::BinaryOption binary);
T read_file(const wasm::fspath& filename, Flags::BinaryOption binary);

// Declare the valid explicit specializations.
extern template std::string read_file<>(const std::string&,
extern template std::string read_file<>(const wasm::fspath&,
Flags::BinaryOption);
extern template std::vector<char> read_file<>(const std::string&,
extern template std::vector<char> read_file<>(const wasm::fspath&,
Flags::BinaryOption);

// Given a string which may be a response file (i.e., a filename starting
// with "@"), if it is a response file read it and return that, or if it
// is not a response file, return it as is.
std::string read_possible_response_file(const std::string&);
std::string read_possible_response_file(const wasm::fspath&);

class Output {
public:
// An empty filename or "-" will open stdout instead.
Output(const std::string& filename, Flags::BinaryOption binary);
Output(const wasm::fspath& filename, Flags::BinaryOption binary);
~Output() = default;
template<typename T> std::ostream& operator<<(const T& v) { return out << v; }

Expand All @@ -70,10 +72,10 @@ class Output {
};

// Copies a file to another file
void copy_file(std::string input, std::string output);
void copy_file(wasm::fspath input, wasm::fspath output);

// Retusn the size of a file
size_t file_size(std::string filename);
size_t file_size(wasm::fspath filename);

} // namespace wasm

Expand Down
5 changes: 3 additions & 2 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "ir/module-utils.h"
#include "parsing.h"
#include "support/debug.h"
#include "support/pchar.h"
#include "wasm-builder.h"
#include "wasm-traversal.h"
#include "wasm-validator.h"
Expand Down Expand Up @@ -1296,7 +1297,7 @@ class WasmBinaryWriter {
sourceMap = set;
sourceMapUrl = url;
}
void setSymbolMap(std::string set) { symbolMap = set; }
void setSymbolMap(wasm::fspath set) { symbolMap = set; }

void write();
void writeHeader();
Expand Down Expand Up @@ -1393,7 +1394,7 @@ class WasmBinaryWriter {

std::ostream* sourceMap = nullptr;
std::string sourceMapUrl;
std::string symbolMap;
wasm::fspath symbolMap;

MixedArena allocator;

Expand Down
28 changes: 14 additions & 14 deletions src/wasm-io.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,17 @@ class ModuleReader : public ModuleIOBase {
}

// read text
void readText(std::string filename, Module& wasm);
void readText(wasm::fspath filename, Module& wasm);
// read binary
void readBinary(std::string filename,
void readBinary(wasm::fspath filename,
Module& wasm,
std::string sourceMapFilename = "");
wasm::fspath sourceMapFilename = "");
// read text or binary, checking the contents for what it is. If `filename` is
// empty, read from stdin.
void
read(std::string filename, Module& wasm, std::string sourceMapFilename = "");
read(wasm::fspath filename, Module& wasm, wasm::fspath sourceMapFilename = "");
// check whether a file is a wasm binary
bool isBinaryFile(std::string filename);
bool isBinaryFile(wasm::fspath filename);

private:
bool DWARF = false;
Expand All @@ -77,11 +77,11 @@ class ModuleReader : public ModuleIOBase {

bool skipFunctionBodies = false;

void readStdin(Module& wasm, std::string sourceMapFilename);
void readStdin(Module& wasm, wasm::fspath sourceMapFilename);

void readBinaryData(std::vector<char>& input,
Module& wasm,
std::string sourceMapFilename);
wasm::fspath sourceMapFilename);
};

class ModuleWriter : public ModuleIOBase {
Expand All @@ -90,8 +90,8 @@ class ModuleWriter : public ModuleIOBase {
// TODO: Remove `emitModuleName`. See the comment in wasm-binary.h
bool emitModuleName = false;

std::string symbolMap;
std::string sourceMapFilename;
wasm::fspath symbolMap;
wasm::fspath sourceMapFilename;
std::string sourceMapUrl;

public:
Expand All @@ -100,8 +100,8 @@ class ModuleWriter : public ModuleIOBase {
ModuleWriter() { setDebugInfo(false); }

void setBinary(bool binary_) { binary = binary_; }
void setSymbolMap(std::string symbolMap_) { symbolMap = symbolMap_; }
void setSourceMapFilename(std::string sourceMapFilename_) {
void setSymbolMap(wasm::fspath symbolMap_) { symbolMap = symbolMap_; }
void setSourceMapFilename(wasm::fspath sourceMapFilename_) {
sourceMapFilename = sourceMapFilename_;
}
void setSourceMapUrl(std::string sourceMapUrl_) {
Expand All @@ -111,15 +111,15 @@ class ModuleWriter : public ModuleIOBase {

// write text
void writeText(Module& wasm, Output& output);
void writeText(Module& wasm, std::string filename);
void writeText(Module& wasm, wasm::fspath filename);
// write binary
void writeBinary(Module& wasm, Output& output);
void writeBinary(Module& wasm, std::string filename);
void writeBinary(Module& wasm, wasm::fspath filename);
// write text or binary, defaulting to binary unless setBinary(false),
// and unless there is no output file (in which case we write text
// to stdout).
void write(Module& wasm, Output& output);
void write(Module& wasm, std::string filename);
void write(Module& wasm, wasm::fspath filename);
};

} // namespace wasm
Expand Down
4 changes: 2 additions & 2 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void WasmBinaryWriter::write() {
if (sourceMap && !sourceMapUrl.empty()) {
writeSourceMapUrl();
}
if (symbolMap.size() > 0) {
if (symbolMap.stdpath().native().size() > 0) {
writeSymbolMap();
}

Expand Down Expand Up @@ -1108,7 +1108,7 @@ void WasmBinaryWriter::writeSourceMapUrl() {
}

void WasmBinaryWriter::writeSymbolMap() {
std::ofstream file(symbolMap);
std::ofstream file(symbolMap.stdpath());
auto write = [&](Function* func) {
file << getFunctionIndex(func->name) << ":" << func->name.str << std::endl;
};
Expand Down
Loading