@@ -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 ();
668740public:
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
803819class WasmBinaryBuilder {
0 commit comments