diff options
Diffstat (limited to 'src/opcode.cc')
-rw-r--r-- | src/opcode.cc | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/src/opcode.cc b/src/opcode.cc index bb68d576..aee21f01 100644 --- a/src/opcode.cc +++ b/src/opcode.cc @@ -18,33 +18,44 @@ #include <algorithm> +#include "feature.h" + namespace wabt { // static Opcode::Info Opcode::infos_[] = { -#define WABT_OPCODE(rtype, type1, type2, mem_size, code, Name, text) \ - {text, Type::rtype, Type::type1, Type::type2, mem_size, code}, +#define WABT_OPCODE(rtype, type1, type2, mem_size, prefix, code, Name, text) \ + {text, Type::rtype, Type::type1, Type::type2, \ + mem_size, prefix, code, PrefixCode(prefix, code)}, #include "opcode.def" #undef WABT_OPCODE }; -#define WABT_OPCODE(rtype, type1, type2, mem_size, code, Name, text) \ +#define WABT_OPCODE(rtype, type1, type2, mem_size, prefix, code, Name, text) \ /* static */ Opcode Opcode::Name##_Opcode(Opcode::Name); #include "opcode.def" #undef WABT_OPCODE // static Opcode::Info Opcode::invalid_info_ = { - "<invalid>", Type::Void, Type::Void, Type::Void, 0, 0, + "<invalid>", Type::Void, Type::Void, Type::Void, 0, 0, 0, 0, }; // static Opcode Opcode::FromCode(uint32_t code) { - auto iter = std::lower_bound( - infos_, infos_ + WABT_ARRAY_SIZE(infos_), code, - [](const Info& info, uint32_t code) { return info.code < code; }); + return FromCode(0, code); +} + +// static +Opcode Opcode::FromCode(uint8_t prefix, uint32_t code) { + uint32_t prefix_code = PrefixCode(prefix, code); + auto iter = + std::lower_bound(infos_, infos_ + WABT_ARRAY_SIZE(infos_), prefix_code, + [](const Info& info, uint32_t prefix_code) { + return info.prefix_code < prefix_code; + }); - if (iter->code != code) + if (iter->prefix_code != prefix_code) return Opcode(Invalid); return Opcode(static_cast<Enum>(iter - infos_)); @@ -65,4 +76,28 @@ Address Opcode::GetAlignment(Address alignment) const { return alignment; } +bool Opcode::IsEnabled(const Features& features) const { + switch (enum_) { + case Opcode::Try: + case Opcode::Catch: + case Opcode::Throw: + case Opcode::Rethrow: + case Opcode::CatchAll: + return features.exceptions_enabled(); + + case Opcode::I32TruncSSatF32: + case Opcode::I32TruncUSatF32: + case Opcode::I32TruncSSatF64: + case Opcode::I32TruncUSatF64: + case Opcode::I64TruncSSatF32: + case Opcode::I64TruncUSatF32: + case Opcode::I64TruncSSatF64: + case Opcode::I64TruncUSatF64: + return features.sat_float_to_int_enabled(); + + default: + return true; + } +} + } // end anonymous namespace |