@@ -300,6 +300,12 @@ class ExpressionParser {
300300 return valueStack.pushResults (results, ¤tOpLoc.value ());
301301 }
302302
303+ // / The local.set and local.tee operations behave similarly and only differ
304+ // / on their return value. This function factorizes the behavior of the two
305+ // / operations in one place.
306+ template <typename OpToCreate>
307+ parsed_inst_t parseSetOrTee (OpBuilder &);
308+
303309private:
304310 std::optional<Location> currentOpLoc;
305311 ParserHead &parser;
@@ -786,6 +792,70 @@ ExpressionParser::parse(OpBuilder &builder,
786792 }
787793}
788794
795+ template <>
796+ inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
797+ WasmBinaryEncoding::OpCode::localGet>(OpBuilder &builder) {
798+ auto id = parser.parseLiteral <uint32_t >();
799+ auto instLoc = *currentOpLoc;
800+ if (failed (id))
801+ return failure ();
802+ if (*id >= locals.size ())
803+ return emitError (instLoc, " Invalid local index. Function has " )
804+ << locals.size () << " accessible locals, received index " << *id;
805+ return {{builder.create <LocalGetOp>(instLoc, locals[*id]).getResult ()}};
806+ }
807+
808+ template <>
809+ inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
810+ WasmBinaryEncoding::OpCode::globalGet>(OpBuilder &builder) {
811+ auto id = parser.parseLiteral <uint32_t >();
812+ auto instLoc = *currentOpLoc;
813+ if (failed (id))
814+ return failure ();
815+ if (*id >= symbols.globalSymbols .size ())
816+ return emitError (instLoc, " Invalid global index. Function has " )
817+ << symbols.globalSymbols .size ()
818+ << " accessible globals, received index " << *id;
819+ auto globalVar = symbols.globalSymbols [*id];
820+ auto globalOp = builder.create <GlobalGetOp>(instLoc, globalVar.globalType ,
821+ globalVar.symbol );
822+
823+ return {{globalOp.getResult ()}};
824+ }
825+
826+ template <typename OpToCreate>
827+ parsed_inst_t ExpressionParser::parseSetOrTee (OpBuilder &builder) {
828+ auto id = parser.parseLiteral <uint32_t >();
829+ if (failed (id))
830+ return failure ();
831+ if (*id >= locals.size ())
832+ return emitError (*currentOpLoc, " Invalid local index. Function has " )
833+ << locals.size () << " accessible locals, received index " << *id;
834+ if (valueStack.empty ())
835+ return emitError (
836+ *currentOpLoc,
837+ " Invalid stack access, trying to access a value on an empty stack." );
838+
839+ parsed_inst_t poppedOp = popOperands (locals[*id].getType ().getElementType ());
840+ if (failed (poppedOp))
841+ return failure ();
842+ return {
843+ builder.create <OpToCreate>(*currentOpLoc, locals[*id], poppedOp->front ())
844+ ->getResults ()};
845+ }
846+
847+ template <>
848+ inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
849+ WasmBinaryEncoding::OpCode::localSet>(OpBuilder &builder) {
850+ return parseSetOrTee<LocalSetOp>(builder);
851+ }
852+
853+ template <>
854+ inline parsed_inst_t ExpressionParser::parseSpecificInstruction<
855+ WasmBinaryEncoding::OpCode::localTee>(OpBuilder &builder) {
856+ return parseSetOrTee<LocalTeeOp>(builder);
857+ }
858+
789859template <typename T>
790860inline Type buildLiteralType (OpBuilder &);
791861
0 commit comments