Skip to content

Commit e601522

Browse files
authored
Refactor stack writing code into a new StackWriter class (#1620)
This separates out the WasmBinaryWriter parts that do stack writing into a separate class, StackWriter. Previously the WasmBinaryWriter did both the general writing and the stack stuff, and the stack stuff has global state, which it manually cleaned up etc. - seems nicer to have it as a separate class, a class focused on just that one thing. Should be no functional changes in this PR. Also add a timeout to the wasm-reduce test, which happened to fail on one of the commits here. It was running slower on that commit for some reason, could have been random - I verified that general wasm writing speed is unaffected by this PR. (But I added the timeout to prevent future random timeouts.)
1 parent 6285642 commit e601522

File tree

3 files changed

+248
-228
lines changed

3 files changed

+248
-228
lines changed

check.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ def run_wasm_reduce_tests():
283283
t = os.path.join(test_dir, t)
284284
# convert to wasm
285285
run_command(WASM_AS + [t, '-o', 'a.wasm'])
286-
run_command(WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec' % WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm'])
286+
run_command(WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec' % WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm', '--timeout=4'])
287287
expected = t + '.txt'
288288
run_command(WASM_DIS + ['c.wasm', '-o', 'a.wast'])
289289
with open('a.wast') as seen:

src/wasm-binary.h

Lines changed: 75 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -652,10 +652,79 @@ inline S32LEB binaryType(Type type) {
652652
return S32LEB(ret);
653653
}
654654

655-
class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
655+
class WasmBinaryWriter;
656+
657+
// Writes out binary format stack machine code for a Binaryen IR expression
658+
659+
class StackWriter : public Visitor<StackWriter> {
660+
public:
661+
// Without a function (offset for a global thing, etc.)
662+
StackWriter(WasmBinaryWriter& parent, BufferWithRandomAccess& o, bool debug=false)
663+
: func(nullptr), parent(parent), o(o), sourceMap(false), debug(debug) {}
664+
665+
// With a function - one is created for the entire function
666+
StackWriter(Function* func, WasmBinaryWriter& parent, BufferWithRandomAccess& o, bool sourceMap=false, bool debug=false)
667+
: func(func), parent(parent), o(o), sourceMap(sourceMap), debug(debug) {
668+
mapLocals();
669+
}
670+
671+
std::map<Type, size_t> numLocalsByType; // type => number of locals of that type in the compact form
672+
673+
// visits a node, emitting the proper code for it
674+
void visit(Expression* curr);
675+
// emits a node, but if it is a block with no name, emit a list of its contents
676+
void visitPossibleBlockContents(Expression* curr);
677+
678+
void visitBlock(Block *curr);
679+
void visitIf(If *curr);
680+
void visitLoop(Loop *curr);
681+
void visitBreak(Break *curr);
682+
void visitSwitch(Switch *curr);
683+
void visitCall(Call *curr);
684+
void visitCallImport(CallImport *curr);
685+
void visitCallIndirect(CallIndirect *curr);
686+
void visitGetLocal(GetLocal *curr);
687+
void visitSetLocal(SetLocal *curr);
688+
void visitGetGlobal(GetGlobal *curr);
689+
void visitSetGlobal(SetGlobal *curr);
690+
void visitLoad(Load *curr);
691+
void visitStore(Store *curr);
692+
void visitAtomicRMW(AtomicRMW *curr);
693+
void visitAtomicCmpxchg(AtomicCmpxchg *curr);
694+
void visitAtomicWait(AtomicWait *curr);
695+
void visitAtomicWake(AtomicWake *curr);
696+
void visitConst(Const *curr);
697+
void visitUnary(Unary *curr);
698+
void visitBinary(Binary *curr);
699+
void visitSelect(Select *curr);
700+
void visitReturn(Return *curr);
701+
void visitHost(Host *curr);
702+
void visitNop(Nop *curr);
703+
void visitUnreachable(Unreachable *curr);
704+
void visitDrop(Drop *curr);
705+
706+
private:
707+
Function* func;
708+
WasmBinaryWriter& parent;
709+
BufferWithRandomAccess& o;
710+
bool sourceMap;
711+
bool debug;
712+
713+
std::map<Index, size_t> mappedLocals; // local index => index in compact form of [all int32s][all int64s]etc
714+
715+
std::vector<Name> breakStack;
716+
717+
int32_t getBreakIndex(Name name);
718+
void emitMemoryAccess(size_t alignment, size_t bytes, uint32_t offset);
719+
720+
void mapLocals();
721+
};
722+
723+
// Writes out wasm to the binary format
724+
725+
class WasmBinaryWriter {
656726
Module* wasm;
657727
BufferWithRandomAccess& o;
658-
Function* currFunction = nullptr;
659728
bool debug;
660729
bool debugInfo = true;
661730
std::ostream* sourceMap = nullptr;
@@ -664,6 +733,9 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
664733

665734
MixedArena allocator;
666735

736+
Function::DebugLocation lastDebugLocation;
737+
size_t lastBytecodeOffset;
738+
667739
void prepare();
668740
public:
669741
WasmBinaryWriter(Module* input, BufferWithRandomAccess& o, bool debug = false) : wasm(input), o(o), debug(debug) {
@@ -703,10 +775,6 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
703775
int32_t getFunctionTypeIndex(Name type);
704776
void writeImports();
705777

706-
std::map<Index, size_t> mappedLocals; // local index => index in compact form of [all int32s][all int64s]etc
707-
std::map<Type, size_t> numLocalsByType; // type => number of locals of that type in the compact form
708-
709-
void mapLocals(Function* function);
710778
void writeFunctionSignatures();
711779
void writeExpression(Expression* curr);
712780
void writeFunctions();
@@ -728,7 +796,7 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
728796

729797
void writeSourceMapProlog();
730798
void writeSourceMapEpilog();
731-
void writeDebugLocation(size_t offset, const Function::DebugLocation& loc);
799+
void writeDebugLocation(Expression* curr, Function* func);
732800

733801
// helpers
734802
void writeInlineString(const char* name);
@@ -746,58 +814,6 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
746814
void emitBuffer(const char* data, size_t size);
747815
void emitString(const char *str);
748816
void finishUp();
749-
750-
// AST writing via visitors
751-
int depth = 0; // only for debugging
752-
753-
void recurse(Expression* curr);
754-
std::vector<Name> breakStack;
755-
Function::DebugLocation lastDebugLocation;
756-
size_t lastBytecodeOffset;
757-
758-
void visit(Expression* curr) {
759-
if (sourceMap && currFunction) {
760-
// Dump the sourceMap debug info
761-
auto& debugLocations = currFunction->debugLocations;
762-
auto iter = debugLocations.find(curr);
763-
if (iter != debugLocations.end() && iter->second != lastDebugLocation) {
764-
writeDebugLocation(o.size(), iter->second);
765-
}
766-
}
767-
Visitor<WasmBinaryWriter>::visit(curr);
768-
}
769-
770-
void visitBlock(Block *curr);
771-
// emits a node, but if it is a block with no name, emit a list of its contents
772-
void recursePossibleBlockContents(Expression* curr);
773-
void visitIf(If *curr);
774-
void visitLoop(Loop *curr);
775-
int32_t getBreakIndex(Name name);
776-
void visitBreak(Break *curr);
777-
void visitSwitch(Switch *curr);
778-
void visitCall(Call *curr);
779-
void visitCallImport(CallImport *curr);
780-
void visitCallIndirect(CallIndirect *curr);
781-
void visitGetLocal(GetLocal *curr);
782-
void visitSetLocal(SetLocal *curr);
783-
void visitGetGlobal(GetGlobal *curr);
784-
void visitSetGlobal(SetGlobal *curr);
785-
void emitMemoryAccess(size_t alignment, size_t bytes, uint32_t offset);
786-
void visitLoad(Load *curr);
787-
void visitStore(Store *curr);
788-
void visitAtomicRMW(AtomicRMW *curr);
789-
void visitAtomicCmpxchg(AtomicCmpxchg *curr);
790-
void visitAtomicWait(AtomicWait *curr);
791-
void visitAtomicWake(AtomicWake *curr);
792-
void visitConst(Const *curr);
793-
void visitUnary(Unary *curr);
794-
void visitBinary(Binary *curr);
795-
void visitSelect(Select *curr);
796-
void visitReturn(Return *curr);
797-
void visitHost(Host *curr);
798-
void visitNop(Nop *curr);
799-
void visitUnreachable(Unreachable *curr);
800-
void visitDrop(Drop *curr);
801817
};
802818

803819
class WasmBinaryBuilder {

0 commit comments

Comments
 (0)