Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always do a full roundtrip in run-roundtrip.py #1661

Merged
merged 1 commit into from
Mar 1, 2023
Merged
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
4 changes: 4 additions & 0 deletions include/wabt/wat-writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@
#define WABT_WAT_WRITER_H_

#include "wabt/common.h"
#include "wabt/feature.h"

namespace wabt {

struct Module;
class Stream;

struct WriteWatOptions {
WriteWatOptions() = default;
WriteWatOptions(const Features& features) : features(features) {}
Features features;
bool fold_exprs = false; // Write folded expressions.
bool inline_export = false;
bool inline_import = false;
Expand Down
18 changes: 12 additions & 6 deletions src/tools/wasm2wat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ static int s_verbose;
static std::string s_infile;
static std::string s_outfile;
static Features s_features;
static WriteWatOptions s_write_wat_options;
static bool s_generate_names = false;
static bool s_generate_names;
static bool s_fold_exprs;
static bool s_inline_import;
static bool s_inline_export;
static bool s_read_debug_names = true;
static bool s_fail_on_custom_section_error = true;
static std::unique_ptr<FileStream> s_log_stream;
Expand Down Expand Up @@ -72,12 +74,12 @@ static void ParseOptions(int argc, char** argv) {
ConvertBackslashToSlash(&s_outfile);
});
parser.AddOption('f', "fold-exprs", "Write folded expressions where possible",
[]() { s_write_wat_options.fold_exprs = true; });
[]() { s_fold_exprs = true; });
s_features.AddOptions(&parser);
parser.AddOption("inline-exports", "Write all exports inline",
[]() { s_write_wat_options.inline_export = true; });
[]() { s_inline_export = true; });
parser.AddOption("inline-imports", "Write all imports inline",
[]() { s_write_wat_options.inline_import = true; });
[]() { s_inline_import = true; });
parser.AddOption("no-debug-names", "Ignore debug names in the binary file",
[]() { s_read_debug_names = false; });
parser.AddOption("ignore-custom-section-errors",
Expand Down Expand Up @@ -132,9 +134,13 @@ int ProgramMain(int argc, char** argv) {
}

if (Succeeded(result)) {
WriteWatOptions wat_options(s_features);
wat_options.fold_exprs = s_fold_exprs;
wat_options.inline_import = s_inline_import;
wat_options.inline_export = s_inline_export;
FileStream stream(!s_outfile.empty() ? FileStream(s_outfile)
: FileStream(stdout));
result = WriteWat(&stream, &module, s_write_wat_options);
result = WriteWat(&stream, &module, wat_options);
}
}
FormatErrorsToFile(errors, Location::Type::Binary);
Expand Down
18 changes: 12 additions & 6 deletions src/tools/wat-desugar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ using namespace wabt;

static const char* s_infile;
static const char* s_outfile;
static WriteWatOptions s_write_wat_options;
static bool s_generate_names;
static bool s_debug_parsing;
static bool s_fold_exprs;
static bool s_generate_names;
static bool s_inline_import;
static bool s_inline_export;
static Features s_features;

static const char s_description[] =
Expand All @@ -64,11 +66,11 @@ static void ParseOptions(int argc, char** argv) {
parser.AddOption("debug-parser", "Turn on debugging the parser of wat files",
[]() { s_debug_parsing = true; });
parser.AddOption('f', "fold-exprs", "Write folded expressions where possible",
[]() { s_write_wat_options.fold_exprs = true; });
[]() { s_fold_exprs = true; });
parser.AddOption("inline-exports", "Write all exports inline",
[]() { s_write_wat_options.inline_export = true; });
[]() { s_inline_export = true; });
parser.AddOption("inline-imports", "Write all imports inline",
[]() { s_write_wat_options.inline_import = true; });
[]() { s_inline_import = true; });
s_features.AddOptions(&parser);
parser.AddOption(
"generate-names",
Expand Down Expand Up @@ -115,8 +117,12 @@ int ProgramMain(int argc, char** argv) {
}

if (Succeeded(result)) {
WriteWatOptions wat_options(s_features);
wat_options.fold_exprs = s_fold_exprs;
wat_options.inline_import = s_inline_import;
wat_options.inline_export = s_inline_export;
FileStream stream(s_outfile ? FileStream(s_outfile) : FileStream(stdout));
result = WriteWat(&stream, module, s_write_wat_options);
result = WriteWat(&stream, module, wat_options);
}
}

Expand Down
11 changes: 8 additions & 3 deletions src/wast-parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,8 @@ Result WastParser::ParseTagModuleField(Module* module) {
}
EXPECT(Lpar);
EXPECT(Tag);
Location loc = GetLocation();

std::string name;
ParseBindVarOpt(&name);

Expand All @@ -1360,20 +1362,23 @@ Result WastParser::ParseTagModuleField(Module* module) {
if (PeekMatchLpar(TokenType::Import)) {
CheckImportOrdering(module);
auto import = std::make_unique<TagImport>(name);
Tag& tag = import->tag;
CHECK_RESULT(ParseInlineImport(import.get()));
CHECK_RESULT(ParseTypeUseOpt(&import->tag.decl));
CHECK_RESULT(ParseUnboundFuncSignature(&import->tag.decl.sig));
CHECK_RESULT(ParseTypeUseOpt(&tag.decl));
CHECK_RESULT(ParseUnboundFuncSignature(&tag.decl.sig));
CHECK_RESULT(ErrorIfLpar({"type", "param", "result"}));
auto field =
std::make_unique<ImportModuleField>(std::move(import), GetLocation());
module->AppendField(std::move(field));
} else {
auto field = std::make_unique<TagModuleField>(GetLocation(), name);
auto field = std::make_unique<TagModuleField>(loc, name);
CHECK_RESULT(ParseTypeUseOpt(&field->tag.decl));
CHECK_RESULT(ParseUnboundFuncSignature(&field->tag.decl.sig));
module->AppendField(std::move(field));
}

AppendInlineExportFields(module, &export_fields, module->tags.size() - 1);

EXPECT(Rpar);
return Result::Ok;
}
Expand Down
10 changes: 9 additions & 1 deletion src/wat-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1435,7 +1435,15 @@ void WatWriter::WriteTable(const Table& table) {

void WatWriter::WriteElemSegment(const ElemSegment& segment) {
WriteOpenSpace("elem");
WriteNameOrIndex(segment.name, elem_segment_index_, NextChar::Space);
// The first name we encounter here, pre-bulk-memory, was intended to refer to
// the table while segment names were not supported at all. For this reason
// we cannot emit a segment name here without bulk-memory enabled, otherwise
// the name will be assumed to be the name of a table and parsing will fail.
if (options_.features.bulk_memory_enabled()) {
WriteNameOrIndex(segment.name, elem_segment_index_, NextChar::Space);
} else {
Writef("(;%u;)", elem_segment_index_);
}

uint8_t flags = segment.GetFlags(&module);

Expand Down
1 change: 1 addition & 0 deletions test/roundtrip/fold-function-references.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
;;; TOOL: run-roundtrip
;;; SKIP: requires fix to parser for typed function refs (#1889)
;;; ARGS: --stdout --fold-exprs --enable-function-references
(module
(type $f32-f32 (func (param f32) (result f32)))
Expand Down
6 changes: 3 additions & 3 deletions test/roundtrip/inline-export-func.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
;;; TOOL: run-roundtrip
;;; ARGS: --stdout --inline-export
(module
(func $foo
(func $foo (param i32)
nop)
(export "foo" (func $foo)))
(;; STDOUT ;;;
(module
(type (;0;) (func))
(func (;0;) (export "foo") (type 0)
(type (;0;) (func (param i32)))
(func (;0;) (export "foo") (type 0) (param i32)
nop))
;;; STDOUT ;;)
42 changes: 13 additions & 29 deletions test/run-roundtrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ def FilesAreEqual(filename1, filename2, verbose=False):
return (OK, '')


def TwoRoundtrips(wat2wasm, wasm2wat, out_dir, filename, verbose):
def DoRoundtrip(wat2wasm, wasm2wat, out_dir, filename, verbose, stdout):
basename = os.path.basename(filename)
basename_noext = os.path.splitext(basename)[0]
wasm1_file = os.path.join(out_dir, basename_noext + '-1.wasm')
wast2_file = os.path.join(out_dir, basename_noext + '-2.wast')
wat2_file = os.path.join(out_dir, basename_noext + '-2.wat')
wasm3_file = os.path.join(out_dir, basename_noext + '-3.wasm')
try:
wat2wasm.RunWithArgs('-o', wasm1_file, filename)
Expand All @@ -68,28 +68,16 @@ def TwoRoundtrips(wat2wasm, wasm2wat, out_dir, filename, verbose):
# test)
return (SKIPPED, None)
try:
wasm2wat.RunWithArgs('-o', wast2_file, wasm1_file)
wat2wasm.RunWithArgs('-o', wasm3_file, wast2_file)
wasm2wat.RunWithArgs('-o', wat2_file, wasm1_file)
wat2wasm.RunWithArgs('-o', wasm3_file, wat2_file)
except Error as e:
return (ERROR, str(e))
return FilesAreEqual(wasm1_file, wasm3_file, verbose)


def OneRoundtripToStdout(wat2wasm, wasm2wat, out_dir, filename, verbose):
basename = os.path.basename(filename)
basename_noext = os.path.splitext(basename)[0]
wasm_file = os.path.join(out_dir, basename_noext + '.wasm')
try:
wat2wasm.RunWithArgs('-o', wasm_file, filename)
except Error:
# if the file doesn't parse properly, just skip it (it may be a "bad-*"
# test)
return (SKIPPED, None)
try:
wasm2wat.RunWithArgs(wasm_file)
except Error as e:
return (ERROR, str(e))
return (OK, '')
if stdout:
with open(wat2_file) as f:
sys.stdout.write(f.read())
return (OK, '')
else:
return FilesAreEqual(wasm1_file, wasm3_file, verbose)


def main(args):
Expand All @@ -102,7 +90,7 @@ def main(args):
default=find_exe.GetDefaultPath(),
help='directory to search for all executables.')
parser.add_argument('--stdout', action='store_true',
help='do one roundtrip and write wast output to stdout')
help='do one roundtrip and write wat output to stdout')
parser.add_argument('--no-error-cmdline',
help='don\'t display the subprocess\'s commandline when '
'an error occurs', dest='error_cmdline',
Expand Down Expand Up @@ -188,12 +176,8 @@ def main(args):
return ERROR

with utils.TempDirectory(options.out_dir, 'roundtrip-') as out_dir:
if options.stdout:
result, msg = OneRoundtripToStdout(wat2wasm, wasm2wat, out_dir,
filename, options.verbose)
else:
result, msg = TwoRoundtrips(wat2wasm, wasm2wat, out_dir, filename,
options.verbose)
result, msg = DoRoundtrip(wat2wasm, wasm2wat, out_dir, filename,
options.verbose, options.stdout)
if result == ERROR:
sys.stderr.write(msg)
return result
Expand Down