SExpr convertInvoke(const SExpr& invoke) { std::string resultString = "call " + currentModule_->exportedFunction(invoke[1].value())->name() + " "; for (std::size_t i = 2; i < invoke.children().size(); i++) { resultString += invoke[i].toString(); resultString += " "; } SExpr result = SExprParser::parseString(resultString); return result; }
WastConverter(const std::string& outDir, const boost::filesystem::path& path) : outDir_(outDir) { baseName_ = path.stem().string(); SExpr fileExpr = SExprParser::parseFile(path.string()); for (const SExpr& child : fileExpr.children()) { const std::string& firstValue = child[0].value(); if (firstValue == "module") { setCurrentModule(child); } else if (firstValue == "assert_invalid") { std::ofstream outStream(generateOutFile("invalid")); outStream << child[1].toString(); outStream.close(); } else if (firstValue == "assert_return_nan") { SExpr functionCall = convertInvoke(child[1]); SExpr newTest = SExprParser::parseString("if (i32.eq (i32.and () " + functionCall.toString() + ") (nop) (unreachable)"); mainFunction_.addChild(newTest); } else if (firstValue == "assert_return") { if (child.children().size() == 2) { SExpr functionCall = convertInvoke(child[1]); mainFunction_.addChild(functionCall); } else { std::string compareType = child[2][0].value().substr(0, 3); SExpr functionCall = convertInvoke(child[1]); SExpr newTest = SExprParser::parseString("if (" + compareType + ".eq " + functionCall.toString() + " " + child[2].toString() +") (nop) (unreachable)"); mainFunction_.addChild(newTest); } } else if (firstValue == "assert_trap") { SExpr functionCall = convertInvoke(child[1]); SExpr mainFunctionWithTrap = mainFunction_; mainFunctionWithTrap.addChild(functionCall); SExpr result = currentModuleExpr_; result.addChild(mainFunctionWithTrap); std::ofstream outStream(generateOutFile("trap")); outStream << result.toString(); outStream.close(); } else if (firstValue == "invoke") { SExpr functionCall = convertInvoke(child[1]); mainFunction_.addChild(functionCall); } else { std::cerr << "Can't handle assert " << child.toString() << std::endl; } } SExpr positiveModule = currentModuleExpr_; positiveModule.addChild(mainFunction_); std::ofstream outStream(generatePositiveOutFile("positive")); outStream << positiveModule.toString(); outStream.close(); }