Invocation(Element& invoke, ModuleInstance* instance, SExpressionWasmBuilder& builder) : instance(instance) { assert(invoke[0]->str() == INVOKE); name = invoke[1]->str(); for (size_t j = 2; j < invoke.size(); j++) { Expression* argument = builder.parseExpression(*invoke[j]); arguments.push_back(argument->dyn_cast<Const>()->value); } }
static void run_asserts(size_t* i, bool* checked, AllocatingModule* wasm, Element* root, std::unique_ptr<SExpressionWasmBuilder>* builder, Name entry) { ShellExternalInterface* interface = nullptr; ModuleInstance* instance = nullptr; if (wasm) { interface = new ShellExternalInterface(); instance = new ModuleInstance(*wasm, interface); if (entry.is()) { Function* function = wasm->getFunction(entry); if (!function) { std::cerr << "Unknown entry " << entry << std::endl; } else { ModuleInstance::LiteralList arguments; for (NameType param : function->params) { arguments.push_back(Literal(param.type)); } try { instance->callExport(entry, arguments); } catch (ExitException&) { } } } } while (*i < root->size()) { Element& curr = *(*root)[*i]; IString id = curr[0]->str(); if (id == MODULE) break; *checked = true; Colors::red(std::cerr); std::cerr << *i << '/' << (root->size() - 1); Colors::green(std::cerr); std::cerr << " CHECKING: "; Colors::normal(std::cerr); std::cerr << curr << '\n'; if (id == ASSERT_INVALID) { // a module invalidity test AllocatingModule wasm; bool invalid = false; std::unique_ptr<SExpressionWasmBuilder> builder; try { builder = std::unique_ptr<SExpressionWasmBuilder>( new SExpressionWasmBuilder(wasm, *curr[1], [&]() { invalid = true; throw ParseException(); }) ); } catch (const ParseException&) { invalid = true; } if (!invalid) { // maybe parsed ok, but otherwise incorrect invalid = !WasmValidator().validate(wasm); } assert(invalid); } else if (id == INVOKE) { assert(wasm); Invocation invocation(curr, instance, *builder->get()); invocation.invoke(); } else { // an invoke test assert(wasm); bool trapped = false; Literal result; try { Invocation invocation(*curr[1], instance, *builder->get()); result = invocation.invoke(); } catch (const TrapException&) { trapped = true; } if (id == ASSERT_RETURN) { assert(!trapped); if (curr.size() >= 3) { Literal expected = builder->get() ->parseExpression(*curr[2]) ->dyn_cast<Const>() ->value; std::cerr << "seen " << result << ", expected " << expected << '\n'; verify_result(expected, result); } else { Literal expected; std::cerr << "seen " << result << ", expected " << expected << '\n'; verify_result(expected, result); } } if (id == ASSERT_TRAP) assert(trapped); } *i += 1; } }