@@ -244,19 +244,13 @@ namespace Section {
244244 extern const char * FunctionSignatures;
245245 extern const char * Functions;
246246 extern const char * ExportTable;
247+ extern const char * Globals;
247248 extern const char * DataSegments;
248249 extern const char * FunctionTable;
249250 extern const char * Names;
250251 extern const char * Start;
251252};
252253
253- enum FunctionEntry {
254- Named = 1 ,
255- Import = 2 ,
256- Locals = 4 ,
257- Export = 8
258- };
259-
260254enum ASTNodes {
261255 CurrentMemory = 0x3b ,
262256 GrowMemory = 0x39 ,
@@ -418,6 +412,8 @@ enum ASTNodes {
418412 CallFunction = 0x16 ,
419413 CallIndirect = 0x17 ,
420414 CallImport = 0x18 ,
415+ GetGlobal = 0x1a ,
416+ SetGlobal = 0x1b ,
421417
422418 Nop = 0x00 ,
423419 Block = 0x01 ,
@@ -486,6 +482,7 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
486482 writeFunctionSignatures ();
487483 writeFunctionTable ();
488484 writeMemory ();
485+ writeGlobals ();
489486 writeExports ();
490487 writeStart ();
491488 writeFunctions ();
@@ -632,6 +629,12 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
632629 finishSection (start);
633630 }
634631
632+ void writeExpression (Expression* curr) {
633+ assert (depth == 0 );
634+ recurse (curr);
635+ assert (depth == 0 );
636+ }
637+
635638 void writeFunctions () {
636639 if (wasm->functions .size () == 0 ) return ;
637640 if (debug) std::cerr << " == writeFunctions" << std::endl;
@@ -657,9 +660,7 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
657660 if (numLocalsByType[i64 ]) o << U32LEB (numLocalsByType[i64 ]) << binaryWasmType (i64 );
658661 if (numLocalsByType[f32 ]) o << U32LEB (numLocalsByType[f32 ]) << binaryWasmType (f32 );
659662 if (numLocalsByType[f64 ]) o << U32LEB (numLocalsByType[f64 ]) << binaryWasmType (f64 );
660- depth = 0 ;
661- recurse (function->body );
662- assert (depth == 0 );
663+ writeExpression (function->body );
663664 size_t size = o.size () - start;
664665 assert (size <= std::numeric_limits<uint32_t >::max ());
665666 if (debug) std::cerr << " body size: " << size << " , writing at " << sizePos << " , next starts at " << o.size () << std::endl;
@@ -668,6 +669,20 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
668669 finishSection (start);
669670 }
670671
672+ void writeGlobals () {
673+ if (wasm->globals .size () == 0 ) return ;
674+ if (debug) std::cerr << " == writeglobals" << std::endl;
675+ auto start = startSection (BinaryConsts::Section::Globals);
676+ o << U32LEB (wasm->globals .size ());
677+ for (auto & curr : wasm->globals ) {
678+ if (debug) std::cerr << " write one" << std::endl;
679+ o << binaryWasmType (curr->type );
680+ writeExpression (curr->init );
681+ o << int8_t (BinaryConsts::End);
682+ }
683+ finishSection (start);
684+ }
685+
671686 void writeExports () {
672687 if (wasm->exports .size () == 0 ) return ;
673688 if (debug) std::cerr << " == writeexports" << std::endl;
@@ -797,7 +812,7 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
797812
798813 // AST writing via visitors
799814
800- int depth; // only for debugging
815+ int depth = 0 ; // only for debugging
801816
802817 void recurse (Expression*& curr) {
803818 if (debug) std::cerr << " zz recurse into " << ++depth << " at " << o.size () << std::endl;
@@ -920,6 +935,15 @@ class WasmBinaryWriter : public Visitor<WasmBinaryWriter, void> {
920935 recurse (curr->value );
921936 o << int8_t (BinaryConsts::SetLocal) << U32LEB (mappedLocals[curr->index ]);
922937 }
938+ void visitGetGlobal (GetGlobal *curr) {
939+ if (debug) std::cerr << " zz node: GetGlobal " << (o.size () + 1 ) << std::endl;
940+ o << int8_t (BinaryConsts::GetGlobal) << U32LEB (curr->index );
941+ }
942+ void visitSetGlobal (SetGlobal *curr) {
943+ if (debug) std::cerr << " zz node: SetGlobal" << std::endl;
944+ recurse (curr->value );
945+ o << int8_t (BinaryConsts::SetGlobal) << U32LEB (curr->index );
946+ }
923947
924948 void emitMemoryAccess (size_t alignment, size_t bytes, uint32_t offset) {
925949 o << U32LEB (Log2 (alignment ? alignment : bytes));
@@ -1230,6 +1254,7 @@ class WasmBinaryBuilder {
12301254 else if (match (BinaryConsts::Section::FunctionSignatures)) readFunctionSignatures ();
12311255 else if (match (BinaryConsts::Section::Functions)) readFunctions ();
12321256 else if (match (BinaryConsts::Section::ExportTable)) readExports ();
1257+ else if (match (BinaryConsts::Section::Globals)) readGlobals ();
12331258 else if (match (BinaryConsts::Section::DataSegments)) readDataSegments ();
12341259 else if (match (BinaryConsts::Section::FunctionTable)) readFunctionTable ();
12351260 else if (match (BinaryConsts::Section::Names)) readNames ();
@@ -1519,7 +1544,7 @@ class WasmBinaryBuilder {
15191544 // process body
15201545 assert (breakStack.empty ());
15211546 assert (expressionStack.empty ());
1522- depth = 0 ;
1547+ assert ( depth == 0 ) ;
15231548 func->body = getMaybeBlock ();
15241549 assert (depth == 0 );
15251550 assert (breakStack.empty ());
@@ -1547,6 +1572,23 @@ class WasmBinaryBuilder {
15471572 }
15481573 }
15491574
1575+ void readGlobals () {
1576+ if (debug) std::cerr << " == readGlobals" << std::endl;
1577+ size_t num = getU32LEB ();
1578+ if (debug) std::cerr << " num: " << num << std::endl;
1579+ for (size_t i = 0 ; i < num; i++) {
1580+ if (debug) std::cerr << " read one" << std::endl;
1581+ auto curr = new Global;
1582+ curr->type = getWasmType ();
1583+ assert (depth == 0 );
1584+ processExpressions ();
1585+ assert (expressionStack.size () == 1 );
1586+ curr->init = popExpression ();
1587+ assert (depth == 0 );
1588+ wasm.addGlobal (curr);
1589+ }
1590+ }
1591+
15501592 std::vector<Name> breakStack;
15511593
15521594 std::vector<Expression*> expressionStack;
@@ -1643,7 +1685,7 @@ class WasmBinaryBuilder {
16431685
16441686 // AST reading
16451687
1646- int depth; // only for debugging
1688+ int depth = 0 ; // only for debugging
16471689
16481690 BinaryConsts::ASTNodes readExpression (Expression*& curr) {
16491691 if (pos == endOfFunction) {
@@ -1665,6 +1707,8 @@ class WasmBinaryBuilder {
16651707 case BinaryConsts::CallIndirect: visitCallIndirect ((curr = allocator.alloc <CallIndirect>())->cast <CallIndirect>()); break ;
16661708 case BinaryConsts::GetLocal: visitGetLocal ((curr = allocator.alloc <GetLocal>())->cast <GetLocal>()); break ;
16671709 case BinaryConsts::SetLocal: visitSetLocal ((curr = allocator.alloc <SetLocal>())->cast <SetLocal>()); break ;
1710+ case BinaryConsts::GetGlobal: visitGetGlobal ((curr = allocator.alloc <GetGlobal>())->cast <GetGlobal>()); break ;
1711+ case BinaryConsts::SetGlobal: visitSetGlobal ((curr = allocator.alloc <SetGlobal>())->cast <SetGlobal>()); break ;
16681712 case BinaryConsts::Select: visitSelect ((curr = allocator.alloc <Select>())->cast <Select>()); break ;
16691713 case BinaryConsts::Return: visitReturn ((curr = allocator.alloc <Return>())->cast <Return>()); break ;
16701714 case BinaryConsts::Nop: visitNop ((curr = allocator.alloc <Nop>())->cast <Nop>()); break ;
@@ -1863,6 +1907,19 @@ class WasmBinaryBuilder {
18631907 curr->value = popExpression ();
18641908 curr->type = curr->value ->type ;
18651909 }
1910+ void visitGetGlobal (GetGlobal *curr) {
1911+ if (debug) std::cerr << " zz node: GetGlobal " << pos << std::endl;
1912+ curr->index = getU32LEB ();
1913+ assert (curr->index < wasm.globals .size ());
1914+ curr->type = wasm.globals [curr->index ]->type ;
1915+ }
1916+ void visitSetGlobal (SetGlobal *curr) {
1917+ if (debug) std::cerr << " zz node: SetGlobal" << std::endl;
1918+ curr->index = getU32LEB ();
1919+ assert (curr->index < wasm.globals .size ());
1920+ curr->value = popExpression ();
1921+ curr->type = curr->value ->type ;
1922+ }
18661923
18671924 void readMemoryAccess (Address& alignment, size_t bytes, Address& offset) {
18681925 alignment = Pow2 (getU32LEB ());
0 commit comments