1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*
* Copyright 2015 WebAssembly Community Group participants
*
* 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.
*/
//
// wasm2asm console tool
//
#include "support/colors.h"
#include "support/command-line.h"
#include "support/file.h"
#include "s2wasm.h"
#include "wasm-linker.h"
#include "wasm-printing.h"
using namespace cashew;
using namespace wasm;
int main(int argc, const char *argv[]) {
bool ignoreUnknownSymbols = false;
bool generateEmscriptenGlue = false;
std::string startFunction;
Options options("s2wasm", "Link .s file into .wast");
options
.add("--output", "-o", "Output file (stdout if not specified)",
Options::Arguments::One,
[](Options *o, const std::string &argument) {
o->extra["output"] = argument;
Colors::disable();
})
.add("--ignore-unknown", "", "Ignore unknown symbols",
Options::Arguments::Zero,
[&ignoreUnknownSymbols](Options *, const std::string &) {
ignoreUnknownSymbols = true;
})
.add("--start", "", "Generate the start method (default: main)",
Options::Arguments::Optional,
[&startFunction](Options *, const std::string &argument) {
startFunction = argument.size() ? argument : "main";
})
.add("--global-base", "-g", "Where to start to place globals",
Options::Arguments::One,
[](Options *o, const std::string &argument) {
o->extra["global-base"] = argument;
})
.add("--allocate-stack", "-s", "Size of the user stack in linear memory",
Options::Arguments::One,
[](Options *o, const std::string &argument) {
o->extra["stack-allocation"] = argument;
})
.add("--initial-memory", "-i", "Initial size of the linear memory",
Options::Arguments::One,
[](Options *o, const std::string &argument) {
o->extra["initial-memory"] = argument;
})
.add("--max-memory", "-m", "Maximum size of the linear memory",
Options::Arguments::One,
[](Options *o, const std::string &argument) {
o->extra["max-memory"] = argument;
})
.add("--emscripten-glue", "-e", "Generate emscripten glue",
Options::Arguments::Zero,
[&generateEmscriptenGlue](Options *, const std::string &) {
generateEmscriptenGlue = true;
})
.add_positional("INFILE", Options::Arguments::One,
[](Options *o, const std::string &argument) {
o->extra["infile"] = argument;
});
options.parse(argc, argv);
auto input(read_file<std::string>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release));
if (options.debug) std::cerr << "Parsing and wasming..." << std::endl;
uint64_t globalBase = options.extra.find("global-base") != options.extra.end()
? std::stoull(options.extra["global-base"])
: 0;
uint64_t stackAllocation =
options.extra.find("stack-allocation") != options.extra.end()
? std::stoull(options.extra["stack-allocation"])
: 0;
uint64_t initialMem =
options.extra.find("initial-memory") != options.extra.end()
? std::stoull(options.extra["initial-memory"])
: 0;
uint64_t maxMem =
options.extra.find("max-memory") != options.extra.end()
? std::stoull(options.extra["max-memory"])
: 0;
if (options.debug) std::cerr << "Global base " << globalBase << '\n';
Linker linker(globalBase, stackAllocation, initialMem, maxMem,
ignoreUnknownSymbols, startFunction, options.debug);
S2WasmBuilder mainbuilder(input.c_str(), options.debug);
linker.linkObject(mainbuilder);
// In the future, there will be code to open additional files/buffers and
// link additional objects, as well as archive members (which only get linked if needed), e.g.:
// S2WasmBuilder lazyObject(some_other_buffer, options.debug)
// linker.linkLazyObject(lazyObject); // calls builder.scan to get symbol info, then build
linker.layout();
std::stringstream meta;
if (generateEmscriptenGlue) {
if (options.debug) std::cerr << "Emscripten gluing..." << std::endl;
// dyncall thunks
linker.emscriptenGlue(meta);
}
if (options.debug) std::cerr << "Printing..." << std::endl;
Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release);
WasmPrinter::printModule(&linker.getOutput().wasm, output.getStream());
output << meta.str() << std::endl;
if (options.debug) std::cerr << "Done." << std::endl;
}
|